Marta Granero i Martí

Tercerca lista - Problema individual 3¶

Eso es un siete o un nueve, ¿o quizás un cuatro?¶

Parece haber una obsesión con conjuntos de datos que representan dígitos escritos a mano. Esto tiene una explicación sencilla. Uno de los primeros retos del OCR fue el reconocimiento de códigos postales en cartas. El clasificar cartas a mano consume demasiado tiempo y no es completamente fiable(además de ser muy aburrido), por lo que tener un sistema eficiente para clasificar el correo era un problema interesante. Uno de los conjuntos de datos más conocidos es MNIST digits. Vamos a utilizar una parte de este conjunto de datos, en concreto un subconjunto de los dígitos, 4, 7 y 9, para experimentar con varios clasificadores. Podéis obtenerlos mediante la función $\texttt{load\_MNIST}$ de la librería $\texttt{apafib}$. Esta función retornará cuatro matrices de datos, el conjunto de entrenamiento y sus etiquetas y el conjunto de test y sus etiquetas. Resuelve los siguientes apartados ilustrando los resultados de la manera que te parezca más adecuada.¶

In [1]:
#!pip install apafib --upgrade --user --quiet
#!pip install pandas==0.24.2 --upgrade --user
In [2]:
import apafib
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels as sm

from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from sklearn.metrics import  ConfusionMatrixDisplay,classification_report,\
                             RocCurveDisplay, PrecisionRecallDisplay,\
                             accuracy_score, f1_score, precision_score, recall_score

from sklearn.model_selection import cross_val_score
from sklearn import set_config

from sklearn.preprocessing import MinMaxScaler, StandardScaler, Binarizer
from sklearn.decomposition import PCA

from statsmodels.genmod.generalized_linear_model import GLM

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.naive_bayes import BernoulliNB, GaussianNB

from sklearn.model_selection import GridSearchCV

from sklearn.neighbors import KNeighborsClassifier
from sklearn.inspection import permutation_importance
from numpy.random import choice

from IPython.display import display, HTML #core.display deprecated
show_html = lambda html: display(HTML(html))

from yellowbrick.target.feature_correlation import feature_correlation
from yellowbrick.classifier import precision_recall_curve
from yellowbrick.classifier.rocauc import roc_auc

import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
/Users/mac/Library/Python/3.10/lib/python/site-packages/statsmodels/tools/_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.
  import pandas.util.testing as tm

Exploración previa de los datos¶

En este problema experimentaremos con distintos clasificadores para ver la capacidad que tiene cada uno a la hora de predecir qué número cualsequiera de los que sigue, 4,7 o 9, es el dígito que se esconde detrás de la imagen codificada en 28x28 píxeles.

Cargamos el conjunto de datos desde la librería $\texttt{apafib}$¶

In [3]:
from apafib import load_MNIST

X_train, X_test, y_train, y_test = apafib.load_MNIST()

#X_train, X_test, y_train, y_test
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)

X_train = pd.DataFrame(X_train, columns = np.arange(X_train.shape[1]))
X_test  = pd.DataFrame(X_test, columns = np.arange(X_test.shape[1]))

#me guardo una copia del dataset de entrenamiento y test ya que mostraré los dígitos escritos a mano a partir 
#del dataset y aplicaré transformaciones que modificaran ambos conjuntos
X_train_copia = X_train
X_test_copia = X_test

data_columns = X_train_copia.columns
data_columns = data_columns.values
#print(data_columns)
(4514, 784) (755, 784) (4514,) (755,)

Breve información del dataset¶

Vemos que tanto el conjunto de datos de entrenamiento como el conjunto de test tienen 784 columnas, lo cuál nos indica que cada imagen esta compuesta por 784 píxeles, i.e 28x28 por imagen.

In [4]:
X_train.info(), X_test.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4514 entries, 0 to 4513
Columns: 784 entries, 0 to 783
dtypes: float64(784)
memory usage: 27.0 MB
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 755 entries, 0 to 754
Columns: 784 entries, 0 to 783
dtypes: float64(784)
memory usage: 4.5 MB
Out[4]:
(None, None)

Breve estadística descriptiva sobre el conjunto de datos¶

Vemos las columnas son los píxeles (28x28 píxeles=784)¶
In [5]:
X_train.describe(include='all')
Out[5]:
0 1 2 3 4 5 6 7 8 9 ... 774 775 776 777 778 779 780 781 782 783
count 4514.0 4514.0 4514.0 4514.0 4514.0 4514.0 4514.0 4514.0 4514.0 4514.0 ... 4514.000000 4514.000000 4514.000000 4514.000000 4514.000000 4514.0 4514.0 4514.0 4514.0 4514.0
mean 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.002261 0.000808 0.000657 0.000089 0.000134 0.0 0.0 0.0 0.0 0.0
std 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.040297 0.024357 0.022564 0.004127 0.008989 0.0 0.0 0.0 0.0 0.0
min 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.0 0.0 0.0 0.0
25% 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.0 0.0 0.0 0.0
50% 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.0 0.0 0.0 0.0
75% 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.0 0.0 0.0 0.0
max 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.992157 0.996078 0.992157 0.250980 0.603922 0.0 0.0 0.0 0.0 0.0

8 rows × 784 columns

Vemos cúantos ejemplos tenemos de cada clase en nuestro conjunto de entrenamiento¶

In [6]:
exemples = dict(zip(list(y_train),[list(y_train).count(i) for i in list(y_train)]))
exemples
Out[6]:
{4: 1426, 9: 1515, 7: 1573}

Extraemos las etiquetas de las clase a las que vamos a clasificar los ejemplos¶

In [7]:
clases = [str(v) for v in sorted(np.unique(y_train))]
clases
Out[7]:
['4', '7', '9']

Visualización del conjunto de datos¶

Visualizamos algunas imágenes de los dígitos que se esconden detrás del conjunto de datos¶

In [8]:
X_train = X_train/255.0
X_test = X_test/255.0

X_train = X_train.values.reshape(-1, 28, 28, 1)
X_test = X_test.values.reshape(-1, 28, 28, 1)

num = 50
num_row = 10
num_col = 5

fig, axes = plt.subplots(num_row, num_col, figsize=(3*num_col,3*num_row))
for i in range(num):
    ax = axes[i//num_col, i%num_col]
    ax.imshow(X_train[:num][i], cmap='gray')
    ax.set_title('Dígito: {}'.format(y_train[:num][i]))
plt.tight_layout()
plt.show()

Estandarizamos el conjunto de entrenamiento y test para poder aplicar después el PCA sobre los datos¶

In [9]:
X_train_standarized = X_train_copia.copy()
scaler = StandardScaler()

X_train_standarized[data_columns] = scaler.fit_transform(X_train_copia[data_columns])
X_train_standarized.describe().T
Out[9]:
count mean std min 25% 50% 75% max
0 4514.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 4514.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2 4514.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 4514.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
4 4514.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
... ... ... ... ... ... ... ... ...
779 4514.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
780 4514.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
781 4514.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
782 4514.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
783 4514.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

784 rows × 8 columns

In [10]:
X_test_standarized = X_test_copia.copy()

X_test_standarized[data_columns] = scaler.transform(X_test_copia[data_columns])
X_test_standarized.describe().T
Out[10]:
count mean std min 25% 50% 75% max
0 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
4 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
... ... ... ... ... ... ... ... ...
779 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
780 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
781 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
782 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
783 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

784 rows × 8 columns

Procedamos con los ejercicios que se nos piden¶

a) Los datos corresponden a imágenes de 28x28 píxeles en niveles de gris. Estos ya están convertidos a vectores y normalizados a la escala [0,1]. Aplica PCA a los datos de entrenamineto y represéntalos en 2D. ¿Se puede ver separabilidad entre las clases? Comenta el resultado¶

El método PCA de scikit-learn devolverá la relación de varianza explicada y todos los parámetros importantes relacionados con PCA¶

In [11]:
myPCA = PCA().fit(X_train_standarized[data_columns]);

#PCA.explained_variance_ratio_ para comprender qué porcentaje de varianza explican los datos
print(myPCA.explained_variance_ratio_)
print(myPCA.explained_variance_ratio_.cumsum())
[6.90543728e-02 5.24610875e-02 4.03322476e-02 3.23154847e-02
 2.83870232e-02 2.27741208e-02 2.19071911e-02 1.96877134e-02
 1.90347242e-02 1.71893389e-02 1.56047355e-02 1.45276514e-02
 1.37900496e-02 1.32646032e-02 1.23999508e-02 1.21353348e-02
 1.15890818e-02 1.10992701e-02 1.06358841e-02 1.03389630e-02
 9.58733637e-03 9.51724367e-03 9.02038508e-03 8.83374746e-03
 8.59362170e-03 8.37622194e-03 8.12496310e-03 8.02405822e-03
 7.48142391e-03 7.42398565e-03 7.17928357e-03 6.79202219e-03
 6.51528819e-03 6.38826900e-03 6.29264281e-03 6.21910693e-03
 6.02283581e-03 5.80343608e-03 5.71887541e-03 5.52796377e-03
 5.48432752e-03 5.31455740e-03 5.24147258e-03 5.16754080e-03
 5.02292071e-03 4.89488740e-03 4.79032346e-03 4.76303608e-03
 4.64443789e-03 4.53563728e-03 4.48379231e-03 4.39781845e-03
 4.34107974e-03 4.26941348e-03 4.12585686e-03 4.09005431e-03
 4.04515330e-03 3.92051719e-03 3.89486503e-03 3.83886034e-03
 3.78988178e-03 3.72863791e-03 3.67036891e-03 3.65357775e-03
 3.61454905e-03 3.60706356e-03 3.51787323e-03 3.44041669e-03
 3.35384054e-03 3.28531189e-03 3.21462499e-03 3.20345570e-03
 3.16849907e-03 3.13708874e-03 3.08096455e-03 3.05623947e-03
 3.00969429e-03 2.96739168e-03 2.86780301e-03 2.86643609e-03
 2.85242480e-03 2.81216410e-03 2.76752247e-03 2.72765191e-03
 2.67117437e-03 2.63407542e-03 2.56174270e-03 2.53540088e-03
 2.51293241e-03 2.49019005e-03 2.42591328e-03 2.41216289e-03
 2.35105849e-03 2.32173783e-03 2.29624498e-03 2.28112244e-03
 2.23829762e-03 2.17955468e-03 2.16476983e-03 2.14394100e-03
 2.11923066e-03 2.09574991e-03 2.05256598e-03 2.03678197e-03
 1.99818376e-03 1.98115230e-03 1.95811422e-03 1.92804413e-03
 1.92483002e-03 1.88963022e-03 1.86528427e-03 1.84206549e-03
 1.83690471e-03 1.80161345e-03 1.79174633e-03 1.75006257e-03
 1.74229278e-03 1.72278756e-03 1.70485309e-03 1.69397141e-03
 1.65645096e-03 1.64744394e-03 1.63202314e-03 1.61931372e-03
 1.58791565e-03 1.56022702e-03 1.55198862e-03 1.54254904e-03
 1.52054555e-03 1.51134530e-03 1.49866261e-03 1.46930392e-03
 1.46295780e-03 1.44615961e-03 1.43738875e-03 1.40622691e-03
 1.39219477e-03 1.35489838e-03 1.35045984e-03 1.32709962e-03
 1.31024908e-03 1.30482284e-03 1.27631074e-03 1.27205918e-03
 1.25937679e-03 1.23318114e-03 1.23048998e-03 1.20929329e-03
 1.19585297e-03 1.18335716e-03 1.16883765e-03 1.15787229e-03
 1.13933383e-03 1.12890799e-03 1.12057768e-03 1.10147457e-03
 1.09365188e-03 1.06988825e-03 1.06644726e-03 1.04228482e-03
 1.03563884e-03 1.03081844e-03 1.02193485e-03 9.96493794e-04
 9.80062534e-04 9.70911006e-04 9.56170903e-04 9.52028855e-04
 9.46690114e-04 9.32128806e-04 9.25661788e-04 9.20884996e-04
 9.05723996e-04 8.94583931e-04 8.90331572e-04 8.80256175e-04
 8.77317994e-04 8.52810484e-04 8.49862376e-04 8.25722334e-04
 8.19945070e-04 8.14769833e-04 8.04800390e-04 7.97376860e-04
 7.88746791e-04 7.77704848e-04 7.77196898e-04 7.59025211e-04
 7.57308809e-04 7.48708326e-04 7.43251538e-04 7.29563095e-04
 7.16601254e-04 7.05383977e-04 7.02056921e-04 6.97341051e-04
 6.89006591e-04 6.83366334e-04 6.80308557e-04 6.71348710e-04
 6.66897711e-04 6.58901623e-04 6.56599358e-04 6.51146801e-04
 6.39215209e-04 6.29438424e-04 6.27421981e-04 6.16607333e-04
 6.07349833e-04 5.97099497e-04 5.94838375e-04 5.89194030e-04
 5.81705835e-04 5.76969787e-04 5.74791609e-04 5.68516992e-04
 5.60685603e-04 5.53847807e-04 5.47179785e-04 5.41009880e-04
 5.39713735e-04 5.32378430e-04 5.30769550e-04 5.19600683e-04
 5.12222168e-04 5.07108022e-04 5.03448828e-04 5.01151351e-04
 4.95934452e-04 4.91865070e-04 4.78806203e-04 4.76131146e-04
 4.73615620e-04 4.64897792e-04 4.62977929e-04 4.58402883e-04
 4.57036919e-04 4.51261791e-04 4.48097002e-04 4.40788166e-04
 4.39455294e-04 4.37918226e-04 4.35392479e-04 4.29280355e-04
 4.22862817e-04 4.20538109e-04 4.18415457e-04 4.16184006e-04
 4.14618348e-04 4.08034429e-04 4.01818105e-04 3.97591187e-04
 3.92852464e-04 3.89552903e-04 3.88147193e-04 3.86338114e-04
 3.77295301e-04 3.73646501e-04 3.71047980e-04 3.69078852e-04
 3.65203105e-04 3.64478802e-04 3.63551555e-04 3.58081827e-04
 3.54880883e-04 3.49226616e-04 3.46742176e-04 3.41709358e-04
 3.38586858e-04 3.35773944e-04 3.34075908e-04 3.30939656e-04
 3.29230731e-04 3.27915971e-04 3.23465052e-04 3.20159158e-04
 3.19348687e-04 3.13239417e-04 3.09486973e-04 3.09414012e-04
 3.07085887e-04 3.03109465e-04 3.02195146e-04 3.00265411e-04
 2.96750077e-04 2.95134797e-04 2.91035273e-04 2.89041823e-04
 2.86325572e-04 2.83077601e-04 2.81774235e-04 2.77538295e-04
 2.76453432e-04 2.74390318e-04 2.72048226e-04 2.71206062e-04
 2.70892416e-04 2.68649328e-04 2.67156945e-04 2.65371135e-04
 2.62728972e-04 2.59927196e-04 2.57711950e-04 2.55678440e-04
 2.53268934e-04 2.48695557e-04 2.48152351e-04 2.45991482e-04
 2.44515522e-04 2.43273417e-04 2.41296836e-04 2.38244301e-04
 2.36130126e-04 2.34119399e-04 2.32296205e-04 2.30014281e-04
 2.27689814e-04 2.27053658e-04 2.25018662e-04 2.22994644e-04
 2.20627461e-04 2.19448792e-04 2.17797332e-04 2.17077899e-04
 2.15329165e-04 2.11354280e-04 2.09072537e-04 2.07841151e-04
 2.07068894e-04 2.04941560e-04 2.03663068e-04 2.01500179e-04
 2.00529607e-04 1.98734783e-04 1.97406658e-04 1.96293459e-04
 1.95006472e-04 1.92674064e-04 1.91433549e-04 1.88992562e-04
 1.88605978e-04 1.87061876e-04 1.85638495e-04 1.83295979e-04
 1.81262807e-04 1.81002271e-04 1.79711473e-04 1.78277847e-04
 1.77955341e-04 1.76329684e-04 1.74117817e-04 1.71389586e-04
 1.69840871e-04 1.68686643e-04 1.68014151e-04 1.67563062e-04
 1.66564225e-04 1.65451109e-04 1.64280205e-04 1.63922950e-04
 1.61392819e-04 1.59121508e-04 1.58865269e-04 1.57803003e-04
 1.55116760e-04 1.54906662e-04 1.53465566e-04 1.52399475e-04
 1.51951004e-04 1.50542392e-04 1.49035737e-04 1.48691438e-04
 1.47835386e-04 1.46055036e-04 1.44687950e-04 1.44202545e-04
 1.43443660e-04 1.41721927e-04 1.39809443e-04 1.39510114e-04
 1.37960409e-04 1.37570655e-04 1.35843504e-04 1.34737135e-04
 1.34192640e-04 1.33420775e-04 1.32455917e-04 1.31418104e-04
 1.31172378e-04 1.30376990e-04 1.29515366e-04 1.29005934e-04
 1.27338605e-04 1.26818787e-04 1.26009871e-04 1.24981442e-04
 1.23839785e-04 1.23094659e-04 1.22533064e-04 1.20689096e-04
 1.19816648e-04 1.19345155e-04 1.18023163e-04 1.16261518e-04
 1.16098390e-04 1.15509047e-04 1.14182808e-04 1.13597042e-04
 1.12399466e-04 1.11726738e-04 1.10895753e-04 1.10167278e-04
 1.09651963e-04 1.08858133e-04 1.07735223e-04 1.07617329e-04
 1.06728113e-04 1.05678296e-04 1.05100637e-04 1.04346320e-04
 1.03922880e-04 1.02574716e-04 1.02074413e-04 1.01552441e-04
 1.00568094e-04 1.00324774e-04 9.96410946e-05 9.89774334e-05
 9.85634788e-05 9.79260630e-05 9.73317256e-05 9.62829231e-05
 9.58243712e-05 9.49745065e-05 9.46403495e-05 9.36315897e-05
 9.34803751e-05 9.18976879e-05 9.10154654e-05 9.03773639e-05
 8.94075036e-05 8.85451813e-05 8.75662399e-05 8.74166824e-05
 8.71665116e-05 8.67705136e-05 8.58939940e-05 8.53824232e-05
 8.46653904e-05 8.43208638e-05 8.39012902e-05 8.34904001e-05
 8.28503499e-05 8.19997950e-05 8.11478275e-05 8.07071677e-05
 8.01804555e-05 7.97418157e-05 7.83857457e-05 7.78597939e-05
 7.75149600e-05 7.66587885e-05 7.62107299e-05 7.58744723e-05
 7.53860857e-05 7.47417890e-05 7.39716787e-05 7.36479799e-05
 7.20497103e-05 7.18135030e-05 7.16569247e-05 7.08129516e-05
 7.06280958e-05 6.98053126e-05 6.95414132e-05 6.93510374e-05
 6.86795381e-05 6.81587470e-05 6.74826826e-05 6.70604564e-05
 6.66998870e-05 6.64076020e-05 6.54939047e-05 6.52769002e-05
 6.49778655e-05 6.39331821e-05 6.34106225e-05 6.27617483e-05
 6.26513624e-05 6.21891321e-05 6.18000392e-05 6.07254395e-05
 6.05968606e-05 5.96412810e-05 5.94175772e-05 5.91735357e-05
 5.85854892e-05 5.77641583e-05 5.71171703e-05 5.68911984e-05
 5.64490291e-05 5.63407895e-05 5.60489319e-05 5.52740692e-05
 5.47580093e-05 5.36890640e-05 5.36303880e-05 5.32242017e-05
 5.28144307e-05 5.23117782e-05 5.19176298e-05 5.18848751e-05
 5.11731300e-05 5.08111165e-05 5.06025780e-05 5.03098209e-05
 5.01236619e-05 4.97074258e-05 4.92177809e-05 4.86666301e-05
 4.81283894e-05 4.73132826e-05 4.72221059e-05 4.69781482e-05
 4.66838290e-05 4.64523021e-05 4.57707372e-05 4.55354957e-05
 4.51428348e-05 4.47603455e-05 4.44460145e-05 4.38421624e-05
 4.37158867e-05 4.31451022e-05 4.28902255e-05 4.27022811e-05
 4.26297977e-05 4.16421340e-05 4.14623309e-05 4.12088953e-05
 4.05136259e-05 4.01739778e-05 3.95388404e-05 3.90355685e-05
 3.86801784e-05 3.80644655e-05 3.79655546e-05 3.75395277e-05
 3.71921573e-05 3.69580434e-05 3.65981189e-05 3.62040434e-05
 3.60400432e-05 3.53563978e-05 3.51061272e-05 3.47644661e-05
 3.43996864e-05 3.38118310e-05 3.31070933e-05 3.30310676e-05
 3.27599762e-05 3.21649265e-05 3.19344900e-05 3.15708695e-05
 3.14620071e-05 3.09931169e-05 3.07393713e-05 3.03038169e-05
 2.99261900e-05 2.95743874e-05 2.84375558e-05 2.83505414e-05
 2.79796324e-05 2.73351988e-05 2.70456579e-05 2.63232691e-05
 2.56413161e-05 2.51828258e-05 2.47309552e-05 2.43470772e-05
 2.39031473e-05 2.33102346e-05 2.31247242e-05 2.20489047e-05
 2.14178016e-05 2.04403249e-05 1.97641509e-05 1.76719246e-05
 1.75466170e-05 1.65143600e-05 1.55565356e-05 1.44886408e-05
 1.31901987e-05 1.21466442e-05 2.18532592e-06 6.36717607e-08
 2.96193938e-31 6.39325037e-32 3.83933574e-32 3.13045456e-32
 1.47968585e-32 4.92354301e-33 4.76983025e-33 4.73348616e-33
 3.88918792e-33 3.47010735e-33 3.11880236e-33 2.83888324e-33
 2.67255883e-33 2.48188245e-33 2.33053260e-33 2.29838816e-33
 2.01195304e-33 1.84449379e-33 1.76141006e-33 1.73852105e-33
 1.68234062e-33 1.62289543e-33 1.55153069e-33 1.49589201e-33
 1.32466899e-33 1.26788037e-33 1.23631635e-33 1.01168977e-33
 1.01079163e-33 9.70841333e-34 9.48904345e-34 8.71110358e-34
 8.63271386e-34 8.14820266e-34 7.80746186e-34 7.36542138e-34
 7.07678198e-34 6.70815076e-34 6.46834961e-34 5.58936420e-34
 4.94357773e-34 4.58000136e-34 4.56491211e-34 4.40004989e-34
 4.16145061e-34 3.97066147e-34 3.23183662e-34 2.92630075e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.74324457e-34 2.74324457e-34 2.74324457e-34
 2.74324457e-34 2.64627725e-34 1.96488700e-34 1.58145054e-34
 1.39273921e-34 1.27406130e-34 1.21823021e-34 1.06106397e-34
 1.05244835e-34 8.87651695e-35 5.96562557e-35 5.36886788e-35
 2.73703365e-35 1.12322463e-35 9.83938260e-36 1.60754684e-36]
[0.06905437 0.12151546 0.16184771 0.19416319 0.22255022 0.24532434
 0.26723153 0.28691924 0.30595397 0.3231433  0.33874804 0.35327569
 0.36706574 0.38033034 0.39273029 0.40486563 0.41645471 0.42755398
 0.43818987 0.44852883 0.45811616 0.46763341 0.47665379 0.48548754
 0.49408116 0.50245738 0.51058235 0.51860641 0.52608783 0.53351182
 0.5406911  0.54748312 0.55399841 0.56038668 0.56667932 0.57289843
 0.57892126 0.5847247  0.59044358 0.59597154 0.60145587 0.60677042
 0.6120119  0.61717944 0.62220236 0.62709725 0.63188757 0.63665061
 0.64129504 0.64583068 0.65031447 0.65471229 0.65905337 0.66332278
 0.66744864 0.6715387  0.67558385 0.67950437 0.68339923 0.68723809
 0.69102797 0.69475661 0.69842698 0.70208056 0.70569511 0.70930217
 0.71282004 0.71626046 0.7196143  0.72289961 0.72611424 0.72931769
 0.73248619 0.73562328 0.73870425 0.74176049 0.74477018 0.74773757
 0.75060537 0.75347181 0.75632424 0.7591364  0.76190392 0.76463157
 0.76730275 0.76993682 0.77249857 0.77503397 0.7775469  0.78003709
 0.782463   0.78487517 0.78722622 0.78954796 0.79184421 0.79412533
 0.79636363 0.79854318 0.80070795 0.80285189 0.80497112 0.80706687
 0.80911944 0.81115622 0.8131544  0.81513556 0.81709367 0.81902172
 0.82094655 0.82283618 0.82470146 0.82654353 0.82838043 0.83018204
 0.83197379 0.83372385 0.83546615 0.83718893 0.83889379 0.84058776
 0.84224421 0.84389165 0.84552368 0.84714299 0.8487309  0.85029113
 0.85184312 0.85338567 0.85490622 0.85641756 0.85791622 0.85938553
 0.86084848 0.86229464 0.86373203 0.86513826 0.86653045 0.86788535
 0.86923581 0.87056291 0.87187316 0.87317798 0.8744543  0.87572635
 0.87698573 0.87821891 0.8794494  0.8806587  0.88185455 0.88303791
 0.88420674 0.88536462 0.88650395 0.88763286 0.88875344 0.88985491
 0.89094856 0.89201845 0.8930849  0.89412718 0.89516282 0.89619364
 0.89721557 0.89821207 0.89919213 0.90016304 0.90111921 0.90207124
 0.90301793 0.90395006 0.90487572 0.90579661 0.90670233 0.90759691
 0.90848725 0.9093675  0.91024482 0.91109763 0.91194749 0.91277322
 0.91359316 0.91440793 0.91521273 0.91601011 0.91679885 0.91757656
 0.91835376 0.91911278 0.91987009 0.9206188  0.92136205 0.92209161
 0.92280821 0.9235136  0.92421566 0.924913   0.925602   0.92628537
 0.92696568 0.92763703 0.92830392 0.92896283 0.92961943 0.93027057
 0.93090979 0.93153923 0.93216665 0.93278326 0.93339061 0.9339877
 0.93458254 0.93517174 0.93575344 0.93633041 0.9369052  0.93747372
 0.93803441 0.93858825 0.93913543 0.93967644 0.94021616 0.94074854
 0.94127931 0.94179891 0.94231113 0.94281824 0.94332169 0.94382284
 0.94431877 0.94481064 0.94528944 0.94576557 0.94623919 0.94670409
 0.94716707 0.94762547 0.94808251 0.94853377 0.94898186 0.94942265
 0.94986211 0.95030003 0.95073542 0.9511647  0.95158756 0.9520081
 0.95242651 0.9528427  0.95325732 0.95366535 0.95406717 0.95446476
 0.95485761 0.95524717 0.95563531 0.95602165 0.95639895 0.95677259
 0.95714364 0.95751272 0.95787792 0.9582424  0.95860595 0.95896404
 0.95931892 0.95966814 0.96001489 0.96035659 0.96069518 0.96103096
 0.96136503 0.96169597 0.9620252  0.96235312 0.96267658 0.96299674
 0.96331609 0.96362933 0.96393882 0.96424823 0.96455532 0.96485843
 0.96516062 0.96546089 0.96575764 0.96605277 0.96634381 0.96663285
 0.96691917 0.96720225 0.96748403 0.96776156 0.96803802 0.96831241
 0.96858446 0.96885566 0.96912655 0.9693952  0.96966236 0.96992773
 0.97019046 0.97045039 0.9707081  0.97096378 0.97121705 0.97146574
 0.9717139  0.97195989 0.9722044  0.97244768 0.97268897 0.97292722
 0.97316335 0.97339747 0.97362976 0.97385978 0.97408747 0.97431452
 0.97453954 0.97476253 0.97498316 0.97520261 0.97542041 0.97563749
 0.97585281 0.97606417 0.97627324 0.97648108 0.97668815 0.97689309
 0.97709676 0.97729826 0.97749879 0.97769752 0.97789493 0.97809122
 0.97828623 0.9784789  0.97867033 0.97885933 0.97904793 0.979235
 0.97942063 0.97960393 0.97978519 0.97996619 0.98014591 0.98032418
 0.98050214 0.98067847 0.98085259 0.98102398 0.98119382 0.9813625
 0.98153052 0.98169808 0.98186465 0.9820301  0.98219438 0.9823583
 0.98251969 0.98267881 0.98283768 0.98299548 0.9831506  0.98330551
 0.98345897 0.98361137 0.98376332 0.98391386 0.9840629  0.98421159
 0.98435943 0.98450548 0.98465017 0.98479437 0.98493782 0.98507954
 0.98521935 0.98535886 0.98549682 0.98563439 0.98577023 0.98590497
 0.98603916 0.98617258 0.98630504 0.98643646 0.98656763 0.98669801
 0.98682752 0.98695653 0.98708387 0.98721068 0.98733669 0.98746168
 0.98758552 0.98770861 0.98783114 0.98795183 0.98807165 0.98819099
 0.98830902 0.98842528 0.98854138 0.98865689 0.98877107 0.98888467
 0.98899707 0.98910879 0.98921969 0.98932986 0.98943951 0.98954837
 0.9896561  0.98976372 0.98987045 0.98997612 0.99008123 0.99018557
 0.99028949 0.99039207 0.99049414 0.9905957  0.99069626 0.99079659
 0.99089623 0.99099521 0.99109377 0.9911917  0.99128903 0.99138531
 0.99148114 0.99157611 0.99167075 0.99176438 0.99185786 0.99194976
 0.99204078 0.99213115 0.99222056 0.99230911 0.99239667 0.99248409
 0.99257126 0.99265803 0.99274392 0.9928293  0.99291397 0.99299829
 0.99308219 0.99316568 0.99324853 0.99333053 0.99341168 0.99349239
 0.99357257 0.99365231 0.99373069 0.99380855 0.99388607 0.99396273
 0.99403894 0.99411481 0.9941902  0.99426494 0.99433891 0.99441256
 0.99448461 0.99455642 0.99462808 0.99469889 0.99476952 0.99483933
 0.99490887 0.99497822 0.9950469  0.99511506 0.99518254 0.9952496
 0.9953163  0.99538271 0.9954482  0.99551348 0.99557846 0.99564239
 0.9957058  0.99576856 0.99583121 0.9958934  0.9959552  0.99601593
 0.99607652 0.99613617 0.99619558 0.99625476 0.99631334 0.99637111
 0.99642822 0.99648512 0.99654156 0.9965979  0.99665395 0.99670923
 0.99676399 0.99681768 0.99687131 0.99692453 0.99697734 0.99702966
 0.99708157 0.99713346 0.99718463 0.99723544 0.99728605 0.99733635
 0.99738648 0.99743619 0.9974854  0.99753407 0.9975822  0.99762951
 0.99767673 0.99772371 0.9977704  0.99781685 0.99786262 0.99790815
 0.9979533  0.99799806 0.9980425  0.99808635 0.99813006 0.99817321
 0.9982161  0.9982588  0.99830143 0.99834307 0.99838453 0.99842574
 0.99846626 0.99850643 0.99854597 0.998585   0.99862368 0.99866175
 0.99869972 0.99873725 0.99877445 0.9988114  0.998848   0.99888421
 0.99892025 0.9989556  0.99899071 0.99902547 0.99905987 0.99909369
 0.99912679 0.99915982 0.99919258 0.99922475 0.99925668 0.99928825
 0.99931972 0.99935071 0.99938145 0.99941175 0.99944168 0.99947125
 0.99949969 0.99952804 0.99955602 0.99958336 0.9996104  0.99963672
 0.99966237 0.99968755 0.99971228 0.99973663 0.99976053 0.99978384
 0.99980696 0.99982901 0.99985043 0.99987087 0.99989064 0.99990831
 0.99992585 0.99994237 0.99995793 0.99997241 0.9999856  0.99999775
 0.99999994 1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.        ]

Scree plot se usa para comprender la cantidad de componentes principales que se deben usar para capturar la varianza deseada en los datos¶

In [12]:
fig = plt.figure(figsize=(10,10));
plt.plot(range(1,len(myPCA.singular_values_ )+1),myPCA.singular_values_ ,alpha=0.8,marker='.');
#La nueva base son los vectores propios de la matriz de covarianza.
y_label = plt.ylabel('Vectores propios');
x_label = plt.xlabel('Componentes');
plt.title('Scree plot');
In [13]:
fig = plt.figure(figsize=(10,10));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
         np.cumsum(myPCA.explained_variance_ratio_),
         c='red',marker='.',
         label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');

Podemos ver que la variancia explicada acumulada pasa del 85% a partir del aproximadamente 125 componentes, las cien primeras componentes acumulan cerca del 80%. Podemos ver que a pesar del gran número de píxeles que tenemos, usamos relativamente pocos para explicar la varianza de los datos. Ya que una sexta parte de estos nos ayudan a describir más del 85% de la varianza.

Pesos que le asigna el PCA a cada componente visualizado con un heatmap¶

Podemos ver que sí que existen correlaciones entre ciertos píxeles, ya que aparecen fuertes correlaciones entre algunas componentes, como se puede ver en el heatmap. Pero també se puede apreciar que no existen correlaciones entre la gran mayoria de estos.

In [14]:
fig, ax = plt.subplots(figsize=(100,50))
sns.heatmap(myPCA.components_, cmap='jet', xticklabels=list(X_train_standarized[X_train_copia.columns]), vmin=-np.max(np.abs(myPCA.components_)), vmax=np.max(np.abs(myPCA.components_)),ax=ax)
Out[14]:
<AxesSubplot: >

Transformamos nuestro conjunto de datos utilizando el PCA¶

In [15]:
transformed_train = myPCA.transform(X_train_standarized[X_train_copia.columns])
transformed_train

X_train_standarized[['PC1','PC2','PC3']] = transformed_train[:,:3]

fig = plt.figure(figsize=(8,8))
_ = sns.scatterplot(x='PC1', y='PC2', data=X_train_standarized, hue=y_train, palette='tab10')
In [16]:
import plotly.express as px

fig = px.scatter_3d(X_train_standarized, x='PC1', y='PC2', z='PC3',color=y_train)
fig.show()

La verdad és que la separación de clases que se puede ver no es del todo clara, ya que la separabilidad que hace de los tres es bastante confusa. Si que parece hacer casi un buen trabajo para el dígito 4 pero apenas queda muy clara la separación de clases entre los tres. Aunque empieza a intuirse un poco, como podemos ver el 7 queda rodeando al conjunto por el extremo izquierdo y debajo, seguido del dígito 9 más adentro y finalmente los datos que quedan más centrados que pertenecen a la clase del dígito 4. Aún así, parece que no ha terminado de agrupar bien los dígitos en función de su similitud y parace confundirse bastante.

También vemos bastantes valores outliers que son de la clase del 4 y 9 que se encuentran un poco alejados de donde se encuentran la mayoria de sus respectivos grupos de puntos. Seguramente han sido manuscritos con un formato poco convencional a lo que entendemos por la forma de escribir el 4 y 9. Además, podemos ver que sobretodo para las clases del 7 y 9 la separabilidad es confusa.

Por lo tanto, se ve claro que no podemos decir mucho acerca de la separabilidad y nos es difícil decir si todas son separables. Es por esto que más adelante probaremos a utilitzar el t-SNE para ver si podemos capturar las no linealidades que hay entre los píxeles.

nou.png

Por ejemplo vemos como este 9 podría confundir al clasificador ya que parece un 4.

set.png Por ejemplo vemos como este 7 podría confundir al clasificador ya que parece un 9 escrito muy rápido.

quatre.png

Este 4 un puede ser fácilmente distingido por cualquiera de nosotros, pero alomejor con la colocación de los píxeles podría confundir al clasificador diciendo que es un 9.

Vemos como representando los loadings, para el 7 y el 4 sí que a lo mejor nos da la ilusión que se percibe de otra manera su cierta separabilidad.¶

In [17]:
loadings = myPCA.components_.T * np.sqrt(myPCA.explained_variance_ratio_)

fig = px.scatter(X_train_standarized, x='PC1', y='PC2', color=y_train)

for i, feature in enumerate(X_train_copia.columns):
    fig.add_shape(type='line',x0=0, y0=0,x1=loadings[i, 0],y1=loadings[i, 1])
    fig.add_annotation(x=loadings[i, 0],y=loadings[i, 1],ax=0, ay=0,xanchor="center",yanchor="bottom",text=feature,)
fig.show()

Ante esta situación se me ocurre realizar un t-SNE ya que como usa distancias alomejor nos permite tener en cuenta ciertas no linearidades en los datos.¶

In [18]:
from sklearn.manifold import TSNE

transformed_train = TSNE(n_components=2, perplexity=10, n_iter=2000, init='pca').fit_transform(X_train_standarized[data_columns])

fig = plt.figure(figsize=(8,8))
sns.scatterplot(x=transformed_train[:,0], y=transformed_train[:,1], hue=y_train, palette='tab10');

Esta es una clara visualización de la separabilidad entre clases que esperábamos ya que vemos un patrón de grupos claro auqnue también es cierto que tenemos pequeños grupos de distintas clases de dígitos que parecen agruparse debido a su parecido de escritura. Por lo tanto vemos que el conjunto de datos es ciertamente sencillo de clasificar correctamente al menos con los píxeles que tenemos. t-SNE nos ha podido capturar las no linealidades y nos muestra una clara separación de los tres dígitos.

Ante esta separabilidad podemos probar de aplicar un LDA para ver como se comporta el discriminante lineal sobre los datos de entrenamiento y vemos que el acierto del modelo para clasificar los dígitos es bueno. O podríamos probar como se comporta QDA por ejemplo.¶

In [19]:
lda = LinearDiscriminantAnalysis()
print(np.mean(cross_val_score(lda,X_train_copia,y_train,cv=10)))
0.9164800934010948
In [20]:
lda_model = LinearDiscriminantAnalysis().fit(X_train_copia, y_train)

coefs = pd.DataFrame(lda_model.coef_)
coefs.columns = data_columns

plt.figure(figsize=(100,20));
sns.heatmap(coefs.abs(), annot=True, linewidths=.5, cbar=True, xticklabels=True, cmap='jet', annot_kws={'size':12});

Podemos ver que ciertos píxeles tienen un peso importante en el modelo.

In [21]:
print(classification_report(lda_model.predict(X_test_copia), y_test))
              precision    recall  f1-score   support

           4       0.90      0.94      0.92       239
           7       0.91      0.94      0.92       241
           9       0.92      0.85      0.88       275

    accuracy                           0.91       755
   macro avg       0.91      0.91      0.91       755
weighted avg       0.91      0.91      0.91       755

Vemos que el acierto del modelo se correponde con el acierto que hemos visto en la validación cruzada.

Vemos que tenemos una precisión parecida en la clasificación de los tres dígitos. Aún así, tenemos un recall menor en la clase del 9 puesto que este tiene un menor porcentaje de predicciones positivas correctas en relación con el total de positivos reales.

Vemos también en la matriz de confusión que errores se cometen en la clasificación¶

In [22]:
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(lda_model, X_test_copia,y_test, ax=plt.subplot());

A continuación ploteamos la curva ROC¶

In [23]:
plt.figure(figsize=(8,8));
roc_auc(lda_model, X_train_copia, y_train, X_test_copia, y_test);

Vemos que para los dígitos 4 i 7 tenemos la misma AUC. Que divergen de la AUC del digito 9 en un 0.02. Podemos ver que aunque no tienen una AUC=1, tenemos casi, un clasificador con predicción perfecta. Es decir, para los tres dígitos la tasa de verdaderos positivos es 1 y la de falsos positivos es 0.

b) Asumiendo que los píxeles son independientes y se distribuyen de manera gausiana, ajusta un modelo Naïve Bayes gausiano y evalúa la calidad del modelo. Cuanto más acerquemos los datos a lo que supone el modelo que ajustamos probablemente obtengamos un mejor resultado. Una posibilidad es binarizar la matriz de datos usando un límite de 0.5 y asumir que los píxeles siguen una distribución de Bernoulli. Transforma los datos a binarios utilizando la función $\texttt{Binarizer}$ y ajusta un Naïve Bayes Bernoulli. Evalúa la calidad del modelo y comenta los resultados.¶

Asumimos que los píxeles son independientes y que siguen una distribución gausiana y ajustamos un modelo de Naïve Bayes Gausiano¶

Ahora, a diferencia del modelo LDA, nuestro modelo de Naïve Bayes gausiano, asumirá que los píxeles son idependientes a diferencia del LDA. Esta implementación nos estimará una matriz de covarianzas independiente por cada etiqueta de clase: 4, 7, 9.

In [24]:
gnb = GaussianNB()
print(np.mean(cross_val_score(gnb,X_train_copia,y_train,cv=10)))
0.5919328728685518

Vemos que usando este modelo no tiene una buena precisión con respecto a la que habia obtenido LDA

In [25]:
gnb_model = GaussianNB().fit(X_train_copia, y_train)

print('Priors:', gnb_model.class_prior_)
print('Means:')
means = pd.DataFrame(gnb_model.theta_)
means.columns= data_columns
means
Priors: [0.31590607 0.34847142 0.33562251]
Means:
Out[25]:
0 1 2 3 4 5 6 7 8 9 ... 774 775 776 777 778 779 780 781 782 783
0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.000000 0.000000 0.000000 0.000000 0.000000 0.0 0.0 0.0 0.0 0.0
1 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.005916 0.001668 0.001177 0.000160 0.000000 0.0 0.0 0.0 0.0 0.0
2 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.000593 0.000676 0.000735 0.000101 0.000399 0.0 0.0 0.0 0.0 0.0

3 rows × 784 columns

In [26]:
print(classification_report(gnb_model.predict(X_test_copia), y_test))
              precision    recall  f1-score   support

           4       0.43      0.92      0.59       118
           7       0.29      0.90      0.44        80
           9       0.97      0.45      0.61       557

    accuracy                           0.57       755
   macro avg       0.56      0.75      0.54       755
weighted avg       0.82      0.57      0.59       755

El acierto con el conjunto de test es parecido al de validación cruzada, y dos de las tres clases no tienen unos valores demasiado buenos, donde la clase del dígito 7 parece la peor de todas.

Vemos que este modelo desbalancea mas la precisión de cada clase, con un acierto peor para la clase 4 y 7.

Tenemos dos situaciones que se nos estan dando:

  • Con la clase del 4 y 7 tenemos un alto recall pero una baja precision lo que significa es que devuelve muchos resultados, pero la mayoría de sus etiquetas predichas son incorrectas en comparación con las etiquetas de entrenamiento.

  • Con la clase del 9 tenemos una alta precision pero poco recall lo que es todo lo contrario, arroja muy pocos resultados, pero la mayoría de sus etiquetas predichas son correctas en comparación con las etiquetas de entrenamiento.

Representamos la matriz de confusión con los errores que comete el modelo¶

In [27]:
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(gnb_model, X_test_copia, y_test, display_labels=clases, ax=plt.subplot());

La curva ROC¶

La curva ROC con más de dos clases nos muestra la tasa de $\frac{verdaderos positivos}{falsos positivos}$ de una clase respecto al resto y una media/media ponderada.

In [28]:
plt.figure(figsize=(8,8));
roc_auc(gnb_model, X_train_copia, y_train, X_test_copia, y_test);

Podemos ver que las AUC del dígito 9 no es demadiaso buena tal y como podíamos esperar con un alto porcentaje de falsos positivos, por otro lado la AUC de las clases 4 y 7 es mejor.

A continuación binarizaremos la matriz de datos usando un límite de 0.5 y asumiremos que los píxeles siguen una distribución de Bernoulli ajustando un modelo de Naïve Bayes Bernoulli.¶

In [29]:
X_train_bin = Binarizer(threshold=0.5).transform(X_train_copia)
X_test_bin  = Binarizer(threshold=0.5).transform(X_test_copia)

X_train_bin.shape, X_test_bin.shape
Out[29]:
((4514, 784), (755, 784))
In [30]:
X_train_bin = pd.DataFrame(X_train_bin)
X_test_bin = pd.DataFrame(X_test_bin)

X_train_bin.shape, X_test_bin.shape

X_train_bin_2 = X_train_bin.copy()

Antes pero de ajustar el modelo podemos aplicar un PCA a la nueva matriz de datos para ver como ha cambiado la separabilidad entre clases¶

In [31]:
myPCA = PCA().fit(X_train_bin[data_columns]);

#PCA.explained_variance_ratio_ para comprender qué porcentaje de varianza explican los datos
print(myPCA.explained_variance_ratio_)
print(myPCA.explained_variance_ratio_.cumsum())

X_train_bin.shape, X_test_bin.shape
[9.86798398e-02 7.04159474e-02 6.36020040e-02 5.31339161e-02
 3.52681806e-02 3.22573620e-02 2.92687983e-02 2.81081504e-02
 2.39018796e-02 2.16883416e-02 2.00622161e-02 1.80625948e-02
 1.71227051e-02 1.48541649e-02 1.27857931e-02 1.22601056e-02
 1.08417855e-02 1.04941546e-02 1.01347878e-02 8.92418783e-03
 8.42672796e-03 8.39248180e-03 7.92445291e-03 7.67216304e-03
 7.26547858e-03 6.76383979e-03 6.59597574e-03 6.32187391e-03
 5.93263536e-03 5.90091617e-03 5.56263645e-03 5.30204256e-03
 5.12971018e-03 4.85244121e-03 4.75997704e-03 4.61781320e-03
 4.41360918e-03 4.37273155e-03 4.06526852e-03 3.95588871e-03
 3.81041156e-03 3.74375705e-03 3.66060359e-03 3.52344667e-03
 3.49995732e-03 3.31201567e-03 3.15033722e-03 3.11434482e-03
 3.02280040e-03 2.98051696e-03 2.84618846e-03 2.78909934e-03
 2.74665561e-03 2.71329826e-03 2.61310964e-03 2.59562078e-03
 2.55321005e-03 2.52241692e-03 2.47551531e-03 2.41137283e-03
 2.37521385e-03 2.28800414e-03 2.24981956e-03 2.19382900e-03
 2.16139375e-03 2.14203895e-03 2.11876075e-03 2.09488626e-03
 2.04760584e-03 2.02373766e-03 1.98127750e-03 1.92705662e-03
 1.90018920e-03 1.86134698e-03 1.85379294e-03 1.83663645e-03
 1.82205620e-03 1.78287565e-03 1.77113778e-03 1.74660904e-03
 1.72013074e-03 1.70774423e-03 1.67188255e-03 1.64253119e-03
 1.62566053e-03 1.60717981e-03 1.58540266e-03 1.57384066e-03
 1.56113555e-03 1.54271278e-03 1.52758166e-03 1.50891465e-03
 1.47906087e-03 1.45207754e-03 1.42431058e-03 1.41221494e-03
 1.40669552e-03 1.38816917e-03 1.36743791e-03 1.35985192e-03
 1.34537646e-03 1.33413717e-03 1.31796140e-03 1.31145211e-03
 1.30437260e-03 1.29486502e-03 1.28165518e-03 1.27678099e-03
 1.25415287e-03 1.23507083e-03 1.22088650e-03 1.20770298e-03
 1.20491738e-03 1.20306865e-03 1.18048109e-03 1.17629956e-03
 1.16734655e-03 1.15378401e-03 1.15194593e-03 1.13981288e-03
 1.13078954e-03 1.11674440e-03 1.11069671e-03 1.10134205e-03
 1.08972615e-03 1.07777265e-03 1.07066318e-03 1.06349559e-03
 1.05719198e-03 1.04944405e-03 1.04042456e-03 1.03573069e-03
 1.03074442e-03 1.02091352e-03 1.01608538e-03 1.00900307e-03
 9.98746368e-04 9.88304753e-04 9.84607681e-04 9.71511141e-04
 9.62230990e-04 9.58754218e-04 9.55635643e-04 9.47094852e-04
 9.41108245e-04 9.35137075e-04 9.25800262e-04 9.21307613e-04
 9.09499199e-04 8.97888146e-04 8.94400181e-04 8.87746524e-04
 8.83773471e-04 8.76684104e-04 8.68235669e-04 8.62673790e-04
 8.55291458e-04 8.50009733e-04 8.45057473e-04 8.41253158e-04
 8.31717885e-04 8.27100045e-04 8.25614454e-04 8.15480878e-04
 8.14286513e-04 8.05906104e-04 8.00796688e-04 7.96109391e-04
 7.94519796e-04 7.85594602e-04 7.82977209e-04 7.79700148e-04
 7.76711828e-04 7.65885923e-04 7.63033953e-04 7.58816942e-04
 7.54659364e-04 7.44889572e-04 7.37053808e-04 7.33610340e-04
 7.30261998e-04 7.25011430e-04 7.20200103e-04 7.15815206e-04
 7.08858203e-04 7.05746267e-04 7.03524279e-04 7.00395356e-04
 6.95550428e-04 6.91398213e-04 6.87295558e-04 6.83692415e-04
 6.76950689e-04 6.69072701e-04 6.65939212e-04 6.62761454e-04
 6.60020653e-04 6.59435212e-04 6.46938361e-04 6.45511470e-04
 6.43407399e-04 6.36852592e-04 6.32326600e-04 6.29064424e-04
 6.24932086e-04 6.21071727e-04 6.14941311e-04 6.12668854e-04
 6.10835455e-04 6.03096616e-04 5.99910316e-04 5.96380621e-04
 5.93975497e-04 5.90131016e-04 5.85771507e-04 5.80926022e-04
 5.75120492e-04 5.71561237e-04 5.67441902e-04 5.61100253e-04
 5.57855464e-04 5.53285354e-04 5.49820453e-04 5.47781751e-04
 5.42649063e-04 5.38337605e-04 5.35100002e-04 5.31700401e-04
 5.22781947e-04 5.21881014e-04 5.14738914e-04 5.14217712e-04
 5.09661825e-04 5.03586191e-04 4.99509339e-04 4.94909433e-04
 4.90163577e-04 4.88464119e-04 4.84587062e-04 4.82223654e-04
 4.80513044e-04 4.76291574e-04 4.69242905e-04 4.65049603e-04
 4.62839502e-04 4.60928268e-04 4.58550521e-04 4.52943767e-04
 4.49041719e-04 4.45190543e-04 4.41593561e-04 4.41096751e-04
 4.38877024e-04 4.34621049e-04 4.31043083e-04 4.26431344e-04
 4.22481408e-04 4.20759511e-04 4.19086833e-04 4.14392809e-04
 4.12367475e-04 4.11452647e-04 4.02959512e-04 4.01350053e-04
 3.99864877e-04 3.97326418e-04 3.93804489e-04 3.89925146e-04
 3.86694479e-04 3.82654222e-04 3.80257242e-04 3.76516964e-04
 3.72924242e-04 3.70684400e-04 3.68154395e-04 3.63851409e-04
 3.61565063e-04 3.59963610e-04 3.55215555e-04 3.51211804e-04
 3.46752540e-04 3.43744340e-04 3.40998336e-04 3.39686347e-04
 3.31673591e-04 3.29525289e-04 3.25993664e-04 3.24733500e-04
 3.22226523e-04 3.20443816e-04 3.16299551e-04 3.14485477e-04
 3.08342379e-04 3.04034344e-04 2.99029148e-04 2.97796746e-04
 2.96375830e-04 2.92736001e-04 2.91812454e-04 2.86393214e-04
 2.84505154e-04 2.80889512e-04 2.78772619e-04 2.76958587e-04
 2.74852838e-04 2.72564847e-04 2.68150468e-04 2.63407197e-04
 2.60589752e-04 2.57453959e-04 2.56233766e-04 2.53213954e-04
 2.50362918e-04 2.46603739e-04 2.43228465e-04 2.41414425e-04
 2.39541979e-04 2.36901331e-04 2.32609357e-04 2.31961344e-04
 2.28438285e-04 2.24517386e-04 2.22968118e-04 2.18678509e-04
 2.14969009e-04 2.14144381e-04 2.11991428e-04 2.09808964e-04
 2.06169803e-04 2.03263299e-04 2.00161172e-04 1.97690155e-04
 1.96313561e-04 1.92906123e-04 1.91316689e-04 1.89201981e-04
 1.86818593e-04 1.83459887e-04 1.82419298e-04 1.80549411e-04
 1.77993216e-04 1.75093863e-04 1.70763435e-04 1.69372391e-04
 1.66622832e-04 1.61761122e-04 1.61115293e-04 1.59300549e-04
 1.57434929e-04 1.55936605e-04 1.55273682e-04 1.54205401e-04
 1.52421389e-04 1.50806017e-04 1.48238961e-04 1.46391244e-04
 1.44028162e-04 1.42212403e-04 1.41223272e-04 1.37246426e-04
 1.36308794e-04 1.34671823e-04 1.33080656e-04 1.32465076e-04
 1.30329486e-04 1.26506833e-04 1.24942744e-04 1.23617101e-04
 1.22373191e-04 1.21344186e-04 1.18966008e-04 1.17825607e-04
 1.16129981e-04 1.13816623e-04 1.12067828e-04 1.11389139e-04
 1.10624665e-04 1.09465208e-04 1.08523646e-04 1.05962625e-04
 1.04902058e-04 1.03308464e-04 1.00360259e-04 9.96922125e-05
 9.81542680e-05 9.65107590e-05 9.63001216e-05 9.51725187e-05
 9.36350641e-05 9.02760938e-05 9.01417386e-05 8.96320984e-05
 8.71310962e-05 8.67546496e-05 8.51812901e-05 8.26372461e-05
 8.15129991e-05 8.06371423e-05 7.85563545e-05 7.72131947e-05
 7.70403713e-05 7.63940619e-05 7.46662773e-05 7.20446998e-05
 7.02455412e-05 6.93631234e-05 6.86414049e-05 6.73050980e-05
 6.63883691e-05 6.51019853e-05 6.42237218e-05 6.35940616e-05
 6.27659536e-05 6.22173437e-05 6.14951949e-05 5.97647363e-05
 5.91207376e-05 5.84643300e-05 5.74801057e-05 5.67875485e-05
 5.63392551e-05 5.50444872e-05 5.41714096e-05 5.26620173e-05
 5.19051757e-05 5.17649695e-05 5.02842806e-05 4.98319165e-05
 4.95129501e-05 4.89616906e-05 4.72960705e-05 4.66765970e-05
 4.58199825e-05 4.46250585e-05 4.44306841e-05 4.28951952e-05
 4.21669020e-05 4.20280791e-05 3.97174154e-05 3.96513451e-05
 3.83120521e-05 3.80815504e-05 3.71227003e-05 3.67371472e-05
 3.65751940e-05 3.55179813e-05 3.51512148e-05 3.47859768e-05
 3.42312849e-05 3.35412594e-05 3.32326056e-05 3.22203835e-05
 3.21044284e-05 3.15462175e-05 3.10160189e-05 3.04694549e-05
 2.97913575e-05 2.94674543e-05 2.91453011e-05 2.78808043e-05
 2.77236068e-05 2.72665793e-05 2.68379427e-05 2.62597852e-05
 2.55039548e-05 2.51671971e-05 2.47633887e-05 2.40094533e-05
 2.34012481e-05 2.27479373e-05 2.26812987e-05 2.20862148e-05
 2.11492952e-05 2.05902495e-05 2.01656202e-05 2.01195572e-05
 1.94797566e-05 1.93270485e-05 1.87820724e-05 1.86516371e-05
 1.84468542e-05 1.79176149e-05 1.76865882e-05 1.66458325e-05
 1.61443651e-05 1.59074920e-05 1.52864376e-05 1.51998708e-05
 1.51827973e-05 1.48990285e-05 1.46495099e-05 1.41370327e-05
 1.39017144e-05 1.38153532e-05 1.30943254e-05 1.27843340e-05
 1.22953110e-05 1.18195252e-05 1.15811754e-05 1.13010252e-05
 1.09883982e-05 1.04959232e-05 1.04750745e-05 1.01876689e-05
 9.94403235e-06 9.70976490e-06 9.43689191e-06 9.33290900e-06
 9.10932240e-06 8.78696455e-06 8.69260515e-06 8.33673784e-06
 8.21084539e-06 8.13849900e-06 7.95688455e-06 7.65345549e-06
 7.18026630e-06 6.91811800e-06 6.75946574e-06 6.67847134e-06
 6.60827899e-06 6.31919071e-06 5.95416943e-06 5.74707056e-06
 5.56694711e-06 5.39032235e-06 5.21366606e-06 5.19893354e-06
 4.95223472e-06 4.76708093e-06 4.50989051e-06 4.46797500e-06
 4.26204159e-06 4.18115481e-06 4.15701256e-06 3.98835822e-06
 3.77539879e-06 3.56581890e-06 3.53663832e-06 3.21958550e-06
 3.10378880e-06 3.05684819e-06 3.02621799e-06 2.73889694e-06
 2.69730203e-06 2.66023779e-06 2.51080690e-06 2.45319987e-06
 2.38420955e-06 2.25307503e-06 2.03850701e-06 1.96147857e-06
 1.84674802e-06 1.60566854e-06 1.42747044e-06 1.35808602e-06
 1.23842396e-06 1.21138234e-06 1.15899041e-06 1.12118114e-06
 9.64891887e-07 8.53512378e-07 8.32853898e-07 7.75026313e-07
 7.63510748e-07 6.22234458e-07 4.24219140e-07 3.45987888e-07
 3.28079315e-07 1.96049565e-32 6.47531246e-33 5.16192985e-33
 4.68768237e-33 4.06556242e-33 4.01784362e-33 3.66222022e-33
 3.09073295e-33 2.61804802e-33 2.47990181e-33 2.37282080e-33
 2.10301805e-33 1.94897094e-33 1.79492023e-33 1.77076194e-33
 1.51853461e-33 1.45629031e-33 1.23013282e-33 1.20454342e-33
 9.80313193e-34 7.00500055e-34 6.84576105e-34 6.56904073e-34
 4.44176191e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 3.35166108e-34
 3.11518758e-34 2.98493256e-34 2.73285252e-34 1.50036002e-34
 8.98153107e-35 5.87713160e-35 2.79741894e-35 4.23372289e-36]
[0.09867984 0.16909579 0.23269779 0.28583171 0.32109989 0.35335725
 0.38262605 0.4107342  0.43463608 0.45632442 0.47638664 0.49444923
 0.51157194 0.5264261  0.53921189 0.551472   0.56231378 0.57280794
 0.58294273 0.59186692 0.60029364 0.60868612 0.61661058 0.62428274
 0.63154822 0.63831206 0.64490803 0.65122991 0.65716254 0.66306346
 0.6686261  0.67392814 0.67905785 0.68391029 0.68867027 0.69328808
 0.69770169 0.70207442 0.70613969 0.71009558 0.71390599 0.71764975
 0.72131035 0.7248338  0.72833376 0.73164577 0.73479611 0.73791045
 0.74093325 0.74391377 0.74675996 0.74954906 0.75229571 0.75500901
 0.75762212 0.76021774 0.76277095 0.76529337 0.76776888 0.77018026
 0.77255547 0.77484348 0.77709329 0.77928712 0.78144852 0.78359056
 0.78570932 0.7878042  0.78985181 0.79187555 0.79385682 0.79578388
 0.79768407 0.79954542 0.80139921 0.80323585 0.8050579  0.80684078
 0.80861192 0.81035853 0.81207866 0.8137864  0.81545828 0.81710081
 0.81872647 0.82033365 0.82191906 0.8234929  0.82505403 0.82659675
 0.82812433 0.82963324 0.8311123  0.83256438 0.83398869 0.83540091
 0.8368076  0.83819577 0.83956321 0.84092306 0.84226844 0.84360257
 0.84492054 0.84623199 0.84753636 0.84883123 0.85011288 0.85138966
 0.85264381 0.85387889 0.85509977 0.85630748 0.85751239 0.85871546
 0.85989594 0.86107224 0.86223959 0.86339337 0.86454532 0.86568513
 0.86681592 0.86793267 0.86904336 0.8701447  0.87123443 0.8723122
 0.87338287 0.87444636 0.87550355 0.876553   0.87759342 0.87862915
 0.8796599  0.88068081 0.8816969  0.8827059  0.88370465 0.88469295
 0.88567756 0.88664907 0.8876113  0.88857005 0.88952569 0.89047278
 0.89141389 0.89234903 0.89327483 0.89419614 0.89510564 0.89600353
 0.89689793 0.89778567 0.89866945 0.89954613 0.90041437 0.90127704
 0.90213233 0.90298234 0.9038274  0.90466865 0.90550037 0.90632747
 0.90715308 0.90796856 0.90878285 0.90958876 0.91038955 0.91118566
 0.91198018 0.91276578 0.91354875 0.91432845 0.91510517 0.91587105
 0.91663409 0.9173929  0.91814756 0.91889245 0.91962951 0.92036312
 0.92109338 0.92181839 0.92253859 0.92325441 0.92396326 0.92466901
 0.92537253 0.92607293 0.92676848 0.92745988 0.92814717 0.92883087
 0.92950782 0.93017689 0.93084283 0.93150559 0.93216561 0.93282505
 0.93347198 0.9341175  0.9347609  0.93539776 0.93603008 0.93665915
 0.93728408 0.93790515 0.93852009 0.93913276 0.9397436  0.94034669
 0.9409466  0.94154298 0.94213696 0.94272709 0.94331286 0.94389379
 0.94446891 0.94504047 0.94560791 0.94616901 0.94672687 0.94728015
 0.94782997 0.94837775 0.9489204  0.94945874 0.94999384 0.95052554
 0.95104832 0.9515702  0.95208494 0.95259916 0.95310882 0.95361241
 0.95411192 0.95460683 0.95509699 0.95558546 0.95607004 0.95655227
 0.95703278 0.95750907 0.95797831 0.95844336 0.9589062  0.95936713
 0.95982568 0.96027863 0.96072767 0.96117286 0.96161445 0.96205555
 0.96249443 0.96292905 0.96336009 0.96378652 0.964209   0.96462976
 0.96504885 0.96546324 0.96587561 0.96628706 0.96669002 0.96709137
 0.96749124 0.96788856 0.96828237 0.96867229 0.96905899 0.96944164
 0.9698219  0.97019841 0.97057134 0.97094202 0.97131018 0.97167403
 0.97203559 0.97239556 0.97275077 0.97310199 0.97344874 0.97379248
 0.97413348 0.97447317 0.97480484 0.97513437 0.97546036 0.97578509
 0.97610732 0.97642776 0.97674406 0.97705855 0.97736689 0.97767092
 0.97796995 0.97826775 0.97856413 0.97885686 0.97914868 0.97943507
 0.97971957 0.98000046 0.98027924 0.98055619 0.98083105 0.98110361
 0.98137176 0.98163517 0.98189576 0.98215321 0.98240945 0.98266266
 0.98291302 0.98315963 0.98340286 0.98364427 0.98388381 0.98412071
 0.98435332 0.98458528 0.98481372 0.98503824 0.98526121 0.98547989
 0.98569486 0.985909   0.98612099 0.9863308  0.98653697 0.98674023
 0.98694039 0.98713808 0.9873344  0.9875273  0.98771862 0.98790782
 0.98809464 0.9882781  0.98846052 0.98864107 0.98881906 0.98899416
 0.98916492 0.98933429 0.98950092 0.98966268 0.98982379 0.98998309
 0.99014053 0.99029646 0.99045174 0.99060594 0.99075837 0.99090917
 0.99105741 0.9912038  0.99134783 0.99149004 0.99163127 0.99176851
 0.99190482 0.99203949 0.99217257 0.99230504 0.99243537 0.99256187
 0.99268682 0.99281043 0.99293281 0.99305415 0.99317312 0.99329094
 0.99340707 0.99352089 0.99363296 0.99374435 0.99385497 0.99396444
 0.99407296 0.99417892 0.99428382 0.99438713 0.99448749 0.99458719
 0.99468534 0.99478185 0.99487815 0.99497332 0.99506696 0.99515723
 0.99524738 0.99533701 0.99542414 0.99551089 0.99559608 0.99567871
 0.99576023 0.99584086 0.99591942 0.99599663 0.99607367 0.99615007
 0.99622473 0.99629678 0.99636702 0.99643639 0.99650503 0.99657233
 0.99663872 0.99670382 0.99676805 0.99683164 0.99689441 0.99695662
 0.99701812 0.99707788 0.99713701 0.99719547 0.99725295 0.99730974
 0.99736608 0.99742112 0.99747529 0.99752795 0.99757986 0.99763162
 0.99768191 0.99773174 0.99778125 0.99783022 0.99787751 0.99792419
 0.99797001 0.99801463 0.99805906 0.99810196 0.99814413 0.99818615
 0.99822587 0.99826552 0.99830383 0.99834192 0.99837904 0.99841578
 0.99845235 0.99848787 0.99852302 0.99855781 0.99859204 0.99862558
 0.99865881 0.99869103 0.99872314 0.99875468 0.9987857  0.99881617
 0.99884596 0.99887543 0.99890457 0.99893245 0.99896018 0.99898744
 0.99901428 0.99904054 0.99906604 0.99909121 0.99911598 0.99913998
 0.99916339 0.99918613 0.99920882 0.9992309  0.99925205 0.99927264
 0.99929281 0.99931293 0.99933241 0.99935173 0.99937052 0.99938917
 0.99940761 0.99942553 0.99944322 0.99945986 0.99947601 0.99949192
 0.9995072  0.9995224  0.99953758 0.99955248 0.99956713 0.99958127
 0.99959517 0.99960899 0.99962208 0.99963487 0.99964716 0.99965898
 0.99967056 0.99968186 0.99969285 0.99970335 0.99971382 0.99972401
 0.99973395 0.99974366 0.9997531  0.99976243 0.99977154 0.99978033
 0.99978902 0.99979736 0.99980557 0.99981371 0.99982167 0.99982932
 0.9998365  0.99984342 0.99985018 0.99985686 0.99986346 0.99986978
 0.99987574 0.99988148 0.99988705 0.99989244 0.99989766 0.99990285
 0.99990781 0.99991257 0.99991708 0.99992155 0.99992581 0.99992999
 0.99993415 0.99993814 0.99994192 0.99994548 0.99994902 0.99995224
 0.99995534 0.9999584  0.99996142 0.99996416 0.99996686 0.99996952
 0.99997203 0.99997448 0.99997687 0.99997912 0.99998116 0.99998312
 0.99998497 0.99998657 0.999988   0.99998936 0.9999906  0.99999181
 0.99999297 0.99999409 0.99999505 0.99999591 0.99999674 0.99999752
 0.99999828 0.9999989  0.99999933 0.99999967 1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.        ]
Out[31]:
((4514, 784), (755, 784))
In [32]:
fig = plt.figure(figsize=(10,10));
plt.plot(range(1,len(myPCA.singular_values_ )+1),myPCA.singular_values_ ,alpha=0.8,marker='.');
#La nueva base son los vectores propios de la matriz de covarianza.
y_label = plt.ylabel('Vectores propios');
x_label = plt.xlabel('Componentes');
plt.title('Scree plot');


X_train_bin.shape, X_test_bin.shape
Out[32]:
((4514, 784), (755, 784))
In [33]:
fig = plt.figure(figsize=(8,6));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
         np.cumsum(myPCA.explained_variance_ratio_),
         c='red',marker='.',
         label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');

X_train_bin.shape, X_test_bin.shape
Out[33]:
((4514, 784), (755, 784))

Podemos ver que la variancia explicada acumulada pasa del 85% a partir del aproximadamente 90/95 componentes, las primeras cincuenta componentes acumulan cerca del 75%. Podemos ver que a pesar del gran número de píxeles que tenemos, ahora con repecto al mismo plot que hemos hecho antes, binarizando la matriz de datos podemos ver una ligera mejora y una mayor explicabilidad de la varianza de los datos con menos componentes.

Pesos que le asigna el nuevo PCA a cada componente visualizado con un heatmap¶

In [34]:
fig, ax = plt.subplots(figsize=(100,50))
sns.heatmap(myPCA.components_, cmap='jet', xticklabels=list(X_train_bin[X_train_copia.columns]), vmin=-np.max(np.abs(myPCA.components_)), vmax=np.max(np.abs(myPCA.components_)),ax=ax)

X_train_bin.shape, X_test_bin.shape
Out[34]:
((4514, 784), (755, 784))
In [35]:
transformed_train = myPCA.transform(X_train_bin_2[X_train_copia.columns])
transformed_train

X_train_bin_2[['PC1','PC2','PC3']] = transformed_train[:,:3]

fig = plt.figure(figsize=(8,8))
_ = sns.scatterplot(x='PC1', y='PC2', data=X_train_bin_2, hue=y_train, palette='tab10')

Se puede empezar a ver una mejor separabilidad de las clases, ahora las clases del dígito 7 y 9 no estan tan juntas como antes. Aún así, vemos que tenemos la mayoria de los datos siguen sin agruparse de forma correcta.

In [36]:
import plotly.express as px

fig = px.scatter_3d(X_train_bin_2, x='PC1', y='PC2', z='PC3',color=y_train)
fig.show()

No podemos apreciar una buena separabilidad entre clases con estas dos componentes aunque los datos estan más dispersos con respecto al PCA con la matriz sin binarizar. Ante esta situación podemos volver a realizar un t-SNE para ver si realmente se puede ver una mejora en la separabilidad.

In [37]:
loadings = myPCA.components_.T * np.sqrt(myPCA.explained_variance_ratio_)

fig = px.scatter(X_train_bin_2, x='PC1', y='PC2', color=y_train)

for i, feature in enumerate(X_train_copia.columns):
    fig.add_shape(type='line',x0=0, y0=0,x1=loadings[i, 0],y1=loadings[i, 1])
    fig.add_annotation(x=loadings[i, 0],y=loadings[i, 1],ax=0, ay=0,xanchor="center",yanchor="bottom",text=feature,)
fig.show()

Ante esta situación realizamos un t-SNE para ver si vemos una mejor separabilidad usando distancias¶

In [38]:
from sklearn.manifold import TSNE

transformed_train = TSNE(n_components=2, perplexity=10, n_iter=2000, init='pca').fit_transform(X_train_bin_2[data_columns])

fig = plt.figure(figsize=(8,8))
sns.scatterplot(x=transformed_train[:,0], y=transformed_train[:,1], hue=y_train, palette='tab10');

Tenemos una mejor visualización de la separabilidad entre clases y también vemos un patrón de grupos claro. Además con repecto al mismo plot que teníamos antes vemos que se han reducido el número de pequeños grupos de distintas clases de dígitos que se agrupan en clases que no son las suyas, puesto que distintos ejemplos de varias clases tienen un parecido de escritura.

Vemos que igualmente el conjunto de datos es ciertamente sencillo de clasificar correctamente al menos con los píxeles que tenemos.

Parece que podríamos decir que este problema tiende a parecer que tiene cierta naturaleza no lineal

Ajustamos el modelo de Naive Bayes Bernoulli¶

In [39]:
bnb = BernoulliNB()

print(np.mean(cross_val_score(bnb, X_train_bin, y_train, cv=10)))
0.8593249023801581

Vemos que obtenemos un mejor error de validación cruzada con respecto al modelo de Naïve Bayes Gausiano pero no tan bueno como al que habíamos obtenido para el LDA.

In [40]:
bnb_model = BernoulliNB().fit(X_train_bin, y_train)
In [41]:
print(classification_report(bnb_model.predict(X_test_bin), y_test, target_names=clases))
              precision    recall  f1-score   support

           4       0.82      0.89      0.86       231
           7       0.88      0.92      0.90       238
           9       0.87      0.78      0.82       286

    accuracy                           0.86       755
   macro avg       0.86      0.87      0.86       755
weighted avg       0.86      0.86      0.86       755

El acierto con el conjunto de test es parecido al de validación cruzada y ahora todas las clases tiene unos valores buenos y sin desbalances notables en la precisión como sucedia antes con el modelo de NB gausiano. Aún así, otra vez, la clase del dígito 9 sigue siendo la peor de todas con respecto al recall que obtiene.

Cabe destacar que ahora la clase que obtiene mejor precision es la del 7, además esta también tiene el mejor recall, lo que nos indica que realiza una muy buena clasificación de esta clase.

Vemos ahora la matriz de confusión¶

In [42]:
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(bnb_model, X_test_bin, y_test, display_labels=clases, ax=plt.subplot());

La curva ROC¶

In [43]:
plt.figure(figsize=(8,8));
roc_auc(bnb_model, X_train_bin, y_train, X_test_bin, y_test);

Vemos que ahora las tres AUC tienen un valor parecido, la mejor siendo la del 7 seguida de la del 4. Vemos que la curva ROC de la clase del 7 tiene la mejor tasa de $\frac{verdaderos positivos}{falsos positivos}$ respecto al resto.

Comentando los resultados¶

Vemos que realmente este modelo último de NB Bernoulli es mejor que el modelo de NB Gausiano puesto que obtenemos un mejor error con el conjunto de test, ya que pasamos de una precision del *0.57* con el conjunto de test del NB Gausiano a una accuracy del *0.86* con el modelo del NB Bernoulli. Vemos que ambos errores del conjunto de test tienen un acierto parecido al de validación cruzada.

Cabe notar que la AUC de los dígitos 4,7 no ha mejorado notablemente, puesto que con el modelo de *NBG* habíamos obtenido unos valors del 0.93 y 0.94 y ahora unos valores del 0.97 y 0.98 esto se debe a que ahora tenemos una precision mayor pero un recall parecido al que ya teníamos con el modelo de *NBG* y además ha mejorado la media/media ponderada

El AUC del dígito 9 ahora si que ha mejorado ya que, hemos pasado de una AUC=0.68 a una AUC del 0.95 con un mayor recall ahora sí.

c) En esta aplicación la calidad del modelo es bastante importante y es probable que las fronteras entre los dígitos sean complejas. Ajusta un modelo K nearest neighbours a la matriz original y la binarizada explorando adecuadamente los hiperparámetros de este modelo. Comenta los resultados¶

Ajustando un modelo de KNN a la matriz original¶

Es importate que todos los atributos se encuenten en la misma escala asi pues, primero de todo los normalizamos el conjunto de entrenamiento y test utilizando el MinMax scaler.

In [44]:
scaler = MinMaxScaler()

X_train_standarized = scaler.fit_transform(X_train_copia)
X_test_standarized = scaler.transform(X_test_copia)
In [45]:
knn =  KNeighborsClassifier()
print(np.mean(cross_val_score(knn, X_train_standarized, y_train, cv=10)))
0.9685404116712123

Vemos que obtenemos un muy buen error de validación cruzada. Además este es mucho mejor que los errores de validación de los modelos de Naïve Bayes Bernoulli y de NB Gausiano.

Explorando el rango de hiperparámetros de KNN¶

Para poder ajustar el modelo lo mejor posible, exploraremos para los distintos hiperpárametros los mejores valores que permiten ajustar los datos usando el modelo KNN.

Exploraremos:

  • Número de vecinos usamos para hacer la predicción
  • Función de peso utilizada en la predicción:
    • uniform: pesos uniformes. Todos los puntos en cada vecindario se ponderan por igual.
    • distance: los vecinos más cercanos de un punto tendrán una mayor influencia que los vecinos más alejados.
  • Métrica a utilizar para el cálculo de la distancia entre vecinos. Usaremos 3 métricas para hacer combinaciones, aunque tenemos estas otras opciones: 'chebyshev', 'cityblock', 'euclidean', 'infinity', 'manhattan', 'minkowski', 'p'
  • Tamaño de hoja. Este hiperparámetro influye en la velocidad de construcción y consulta, así como la memoria requerida para almacenar el árbol. Si obtenemos el mismo resultado para distintos tamaños de hoja, mejor coger el que tenga un mayor tamaño, así podemos reducir un poco el tiempo de construcción del árbol, porque necesitaremos crear menos nodos

Notamos que para el conjunto de hiperparámetros que siguen tendremos: 504 combinaciones(12·2·3·7)

In [46]:
param = {'n_neighbors':[1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 15, 17],
         'weights':['distance', 'uniform'],
         'metric': ['l2', 'l1', 'cosine'],
         'leaf_size':[1, 5, 10, 15, 20, 25, 30]}
kne =  KNeighborsClassifier()
gknn =  GridSearchCV(kne, param, cv=10, n_jobs=-1, refit=True);
gknn.fit(X_train_standarized, y_train);
In [47]:
show_html(pd.DataFrame(gknn.cv_results_).loc[:,['params', 'mean_test_score','rank_test_score']].sort_values(by='rank_test_score').head().to_html())
params mean_test_score rank_test_score
55 {'leaf_size': 1, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} 0.972309 1
199 {'leaf_size': 10, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} 0.972309 1
415 {'leaf_size': 25, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} 0.972309 1
127 {'leaf_size': 5, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} 0.972309 1
343 {'leaf_size': 20, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} 0.972309 1

Como podemos ver tenemos un conjuto de hiperparámetros que da el mismo resultado hasta el sexto decimal. Vemos que todo el conjunto de hiperparámetros obtiene el mismo resultado con la misma métrica, el mismo número de vecinos, la misma función de peso, pero distinto tamaño de hoja.

Así que, a igualdad de resultados, mejor quedarnos con el resultado que usa un tamaño de hoja más grande, para reducir el tiempo de construcción del árbol y además con un tamaño de hoja grande podemos tener un mejor tiempo de consulta.

Así que nos podemos queda con la combinación 415 de:

{'leaf_size': 25, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'}

In [48]:
print(classification_report(gknn.predict(X_test_standarized), y_test, target_names=clases))
              precision    recall  f1-score   support

           4       0.97      0.99      0.98       246
           7       0.98      0.97      0.98       252
           9       0.96      0.96      0.96       257

    accuracy                           0.97       755
   macro avg       0.97      0.97      0.97       755
weighted avg       0.97      0.97      0.97       755

Podemos ver que el acierto en el test es consistente con la validación cruzada que hemos obtenido arriba. Como podemos apreciar la mejor clase de todas es la clase del dígito 4 con la mejor relación precision-recall, seguida de la clase del 7 y finalmente la peor clase, la del dígito 9.

In [49]:
ConfusionMatrixDisplay.from_estimator(gknn, X_test_standarized,y_test)
Out[49]:
<sklearn.metrics._plot.confusion_matrix.ConfusionMatrixDisplay at 0x131f9ee30>
In [50]:
roc_auc(gknn, X_train_standarized, y_train, X_test_standarized, y_test);

Como podemos ver obtenenemos un AUC perfecta para la clase del dígito 4, seguida de unas AUC de 0.99 para las otras clases. Por lo tanto, para la clase del 4, tenemos un 100% de predicciones correctas.

Podemos usar permutation importance para ver que píxeles parecen ser los más importantes para la clasificación.

In [51]:
c = choice(X_test_copia.shape[0], size=300, replace=False)
pi = permutation_importance(gknn, X_test_standarized[c], y_test[c], n_jobs=-1, random_state=42)
var_imp = pd.DataFrame({'importance': pi.importances_mean}, index=data_columns[:])
In [52]:
var_imp.sort_values(by='importance').plot.barh(figsize=(60,80), legend=False);

En esta ejecución los píxeles más importantes, parecen ser los que se encuentran en el rango [200-400] aunque si lo volvemos a ejecutar veremos que otros píxeles tendran más o menos importancia, aunque suele ser más o menos consistente. Puede pasar que un píxel a lo mejor sea el que tenga más peso en la decisión y después ver que ese peso, para otra ejecución, tiene un peso que su importancia este en la mitad de la tabla.

Ajustando un modelo de KNN a la matriz binarizada¶

In [53]:
X_train_bin = Binarizer(threshold=0.5).transform(X_train_copia)
X_test_bin  = Binarizer(threshold=0.5).transform(X_test_copia)
In [54]:
X_train_bin = pd.DataFrame(X_train_bin)
X_test_bin = pd.DataFrame(X_test_bin)
In [55]:
scaler = MinMaxScaler()

X_train_standarized_bin = scaler.fit_transform(X_train_bin)
X_test_standarized_bin = scaler.transform(X_test_bin)
In [56]:
knn_bin =  KNeighborsClassifier()
print(np.mean(cross_val_score(knn_bin, X_train_standarized_bin, y_train, cv=10)))
0.9599032631516982

Vemos que obtenemos un muy buen error de validación cruzada. Además este es mucho mejor que los errores de validación de los modelos de Naïve Bayes Bernoulli y de NB Gausiano pero no tant bueno como el KNN con la matriz de datos sin binarizar. Aún así conseguimos un buen error de validación cruzada.

In [57]:
param = {'n_neighbors':[1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 15, 17],
         'weights':['distance', 'uniform'],
         'metric': ['l2', 'l1', 'cosine'],
         'leaf_size':[1, 5, 10, 15, 20, 25, 30]}
kne =  KNeighborsClassifier()
gknn =  GridSearchCV(kne, param, cv=10, n_jobs=-1, refit=True);
gknn.fit(X_train_standarized_bin, y_train);
In [58]:
show_html(pd.DataFrame(gknn.cv_results_).loc[:,['params', 'mean_test_score','rank_test_score']].sort_values(by='rank_test_score').head().to_html())
params mean_test_score rank_test_score
199 {'leaf_size': 10, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} 0.966325 1
55 {'leaf_size': 1, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} 0.966325 1
415 {'leaf_size': 25, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} 0.966325 1
127 {'leaf_size': 5, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} 0.966325 1
271 {'leaf_size': 15, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'} 0.966325 1

Otra vez, podemos ver como tenemos un conjuto de hiperparámetros que da el mismo resultado hasta el sexto decimal.

Asimismo podemos ver tenemos un conjuto de hiperparámetros que da el mismo resultado hasta el sexto decimal. Vemos que todo el conjunto de hiperparámetros obtiene el mismo resultado con la misma métrica, el mismo número de vecinos, la misma función de peso, pero distinto tamaño de hoja.

Así que, a igualdad de resultados, mejor quedarnos con el resultado que usa un tamaño de hoja más grande, para reducir el tiempo de construcción del árbol y además con un tamaño de hoja grande podemos tener un mejor tiempo de consulta.

Así que nos podemos queda con la misma combinación 415:

{'leaf_size': 25, 'metric': 'cosine', 'n_neighbors': 4, 'weights': 'uniform'}

In [59]:
print(classification_report(gknn.predict(X_test_standarized_bin), y_test, target_names=clases))
              precision    recall  f1-score   support

           4       0.96      0.98      0.97       245
           7       0.97      0.95      0.96       254
           9       0.95      0.94      0.94       256

    accuracy                           0.96       755
   macro avg       0.96      0.96      0.96       755
weighted avg       0.96      0.96      0.96       755

Podemos ver que el acierto en el test es consistente con la validación cruzada que hemos obtenido arriba.

Como podemos apreciar la mejor clase de todas es la clase del dígito 4 como había ocurrido antes con el KNN con la matriz bin binarizar. Seguimos teniendo para la clase del 4 la mejor relación precision-recall, seguida de la clase del 7 y finalmente la del dígito 9.

Apenas hay mucha diferencia entre ambos modelos, aunque podemos notar que para el modelo KNN si no binarizamos la matriz de datos funciona un poco de mejor forma.

In [60]:
ConfusionMatrixDisplay.from_estimator(gknn, X_test_standarized_bin, y_test)
Out[60]:
<sklearn.metrics._plot.confusion_matrix.ConfusionMatrixDisplay at 0x13621b340>
In [61]:
roc_auc(gknn, X_train_standarized_bin, y_train, X_test_standarized_bin, y_test);

Ahora ninguna AUC tiene es de 1.0, però podemos decir que ahora para todas las clases las predicciones son en un 99% correctas. Lo que casi, nos permite decir que tenemos un clasificador perfecto.

In [62]:
c = choice(X_test_copia.shape[0], size=300, replace=False)
pi = permutation_importance(gknn, X_test_standarized_bin[c], y_test[c], n_jobs=-1, random_state=42)
var_imp = pd.DataFrame({'importance': pi.importances_mean}, index=data_columns[:])
In [63]:
var_imp.sort_values(by='importance').plot.barh(figsize=(60,80), legend=False);

En esta ejecución los píxeles más importantes, parecen ser los que se encuentran en el rango [400-500] y sucede exactamente lo mismo que se ha comentado en el permutation importance realizado en celdas anteriores.

d) Habás observado al hacer el PCA que el número de componentes necesario para explicar la variancia de los datos no es muy grande respecto a su dimensionalidad real. Elige un número de componentes, obtén las matrices de datos transformadas. Ajusta un modelo Naïve Bayes y un K nearest neighbours a estos datos explorando adecuadamente sus hiperparámetros. Evalúa la calidad de los modelos. ¿Por qué sería más adecuado usar el Naïve Bayes con esta transformación? ¿Qué ventajas/inconvenientes tendría el trabajar con los datos transformados? ¿Qué modelo de entre todos elegirías para reconocer códigos postales? Razona tu respuesta.¶

Totalmente cierto, como se ha podido ver antes, con alrededor de 100 componentes podíamos explicar el 85% de la variancia de nuestros datos usando el StandardScaler() para los modelos de: Naïve Bayes Gausiano y para Naïve Bayes Bernoulli. Cabe notar que para la matriz de datos binarizada que ha usando el modelo de NB B hacían falta un poco menos de componentes, alrededor de 90/95, para explicar el 85% de la variancia. Pero aún así, con entorno a una septima parte de las componentes ya nos era suficiente.

Podemos probar cúantas componentes necesitariamos aplicando PCA usando el conjunto de datos original y usando la matriz binarizada, pero esta vez escalando ambos conjuntos usando MinMaxScaler().

Aplicación del PCA con el conjunto de datos original usando MinMaxScaler()¶

In [64]:
X_train_standarized = X_train_copia.copy()
scaler = MinMaxScaler()

X_train_standarized[data_columns] = scaler.fit_transform(X_train_copia[data_columns])
X_train_standarized.describe().T

X_test_standarized = X_test_copia.copy()

X_test_standarized[data_columns] = scaler.transform(X_test_copia[data_columns])
X_test_standarized.describe().T
Out[64]:
count mean std min 25% 50% 75% max
0 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
4 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
... ... ... ... ... ... ... ... ...
779 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
780 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
781 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
782 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
783 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

784 rows × 8 columns

In [66]:
myPCA = PCA().fit(X_train_standarized[data_columns]);

#PCA.explained_variance_ratio_ para comprender qué porcentaje de varianza explican los datos
print(myPCA.explained_variance_ratio_)
print(myPCA.explained_variance_ratio_.cumsum())
[1.20383131e-01 8.56801659e-02 7.67407439e-02 6.40229908e-02
 4.16757764e-02 3.79377822e-02 3.41932642e-02 3.27309530e-02
 2.73394291e-02 2.47745725e-02 2.26181525e-02 2.07564019e-02
 1.94411296e-02 1.66629127e-02 1.43462196e-02 1.36043031e-02
 1.20402580e-02 1.16023600e-02 1.10713421e-02 9.53762233e-03
 9.12810753e-03 9.01239016e-03 8.40022959e-03 8.36535886e-03
 7.83768807e-03 7.11331418e-03 6.88622497e-03 6.46543726e-03
 6.22964289e-03 6.07464483e-03 5.59678067e-03 5.39706460e-03
 5.23110454e-03 4.91791764e-03 4.73827562e-03 4.62125854e-03
 4.38231360e-03 4.24869069e-03 3.95712482e-03 3.87665575e-03
 3.73882802e-03 3.63387451e-03 3.38219686e-03 3.36559090e-03
 3.27953394e-03 3.15811098e-03 3.00375786e-03 2.90536973e-03
 2.80883092e-03 2.70035334e-03 2.59121925e-03 2.48537582e-03
 2.43805641e-03 2.40658228e-03 2.29004223e-03 2.26207479e-03
 2.23294914e-03 2.19105757e-03 2.10388622e-03 2.02611019e-03
 1.98158382e-03 1.94959243e-03 1.83706953e-03 1.79029368e-03
 1.76901487e-03 1.74210222e-03 1.69874566e-03 1.65060979e-03
 1.60405721e-03 1.54911579e-03 1.49618324e-03 1.46236641e-03
 1.45953475e-03 1.41124118e-03 1.40447815e-03 1.34725974e-03
 1.33419148e-03 1.29495413e-03 1.27709068e-03 1.25962973e-03
 1.22236479e-03 1.20696147e-03 1.17722723e-03 1.16339610e-03
 1.14150277e-03 1.10320073e-03 1.07251413e-03 1.04520335e-03
 1.04087326e-03 1.02679968e-03 1.01010624e-03 9.80770572e-04
 9.62998995e-04 9.32614985e-04 9.30804237e-04 9.14732226e-04
 9.05511556e-04 8.92341766e-04 8.84341686e-04 8.73536188e-04
 8.63054563e-04 8.50156658e-04 8.32389148e-04 8.25598666e-04
 8.15247236e-04 8.08028172e-04 7.91302452e-04 7.85404750e-04
 7.68613596e-04 7.62997156e-04 7.52282715e-04 7.35002446e-04
 7.20568043e-04 7.06484310e-04 6.97263638e-04 6.81596550e-04
 6.77906412e-04 6.60453361e-04 6.48927386e-04 6.41572278e-04
 6.35598606e-04 6.28607152e-04 6.17565913e-04 6.11277213e-04
 6.10560673e-04 5.94181475e-04 5.91738684e-04 5.79485275e-04
 5.64615772e-04 5.61173318e-04 5.53010570e-04 5.48002413e-04
 5.38876791e-04 5.33353192e-04 5.25675302e-04 5.20542772e-04
 5.09767029e-04 5.07400517e-04 4.97089354e-04 4.93006585e-04
 4.89830979e-04 4.85156499e-04 4.79212952e-04 4.73043440e-04
 4.68030024e-04 4.59149638e-04 4.57331927e-04 4.54550600e-04
 4.47811280e-04 4.45245655e-04 4.33549566e-04 4.27363247e-04
 4.24458149e-04 4.21488667e-04 4.15448100e-04 4.11455850e-04
 4.07727624e-04 4.04182535e-04 3.92574659e-04 3.89106175e-04
 3.87673722e-04 3.85686607e-04 3.82900983e-04 3.71669607e-04
 3.69098098e-04 3.64240748e-04 3.59976313e-04 3.52988169e-04
 3.51439375e-04 3.50770920e-04 3.47676104e-04 3.46234990e-04
 3.41475085e-04 3.32648984e-04 3.29760419e-04 3.28500726e-04
 3.23960735e-04 3.23118017e-04 3.19933811e-04 3.17524313e-04
 3.12045281e-04 3.10210430e-04 3.06341098e-04 3.01380374e-04
 2.99430939e-04 2.95650882e-04 2.93313024e-04 2.91237244e-04
 2.87681808e-04 2.86068943e-04 2.82208866e-04 2.79145832e-04
 2.73678144e-04 2.70658398e-04 2.69869138e-04 2.67332912e-04
 2.62049175e-04 2.58597831e-04 2.56811859e-04 2.55148242e-04
 2.53343998e-04 2.51222907e-04 2.48252708e-04 2.47629902e-04
 2.46672984e-04 2.41584593e-04 2.40404456e-04 2.37687674e-04
 2.33443547e-04 2.31601504e-04 2.30568966e-04 2.27444887e-04
 2.27143627e-04 2.23414627e-04 2.23036066e-04 2.19669640e-04
 2.18027913e-04 2.16331902e-04 2.14673447e-04 2.13041436e-04
 2.10798016e-04 2.08797680e-04 2.07490612e-04 2.06291342e-04
 2.04426693e-04 2.00319237e-04 1.99545251e-04 1.97714826e-04
 1.94982655e-04 1.93454705e-04 1.89455670e-04 1.88596622e-04
 1.87162061e-04 1.86305958e-04 1.84219865e-04 1.82584957e-04
 1.81010358e-04 1.79490055e-04 1.78205912e-04 1.76650458e-04
 1.75871383e-04 1.74062342e-04 1.72694519e-04 1.70991313e-04
 1.69959843e-04 1.67336180e-04 1.66976203e-04 1.66272770e-04
 1.63887634e-04 1.63498965e-04 1.62859612e-04 1.61039180e-04
 1.57357726e-04 1.56504042e-04 1.54592775e-04 1.54077879e-04
 1.52685648e-04 1.51339592e-04 1.50951728e-04 1.49467223e-04
 1.48684825e-04 1.46497539e-04 1.45101791e-04 1.43952678e-04
 1.43322105e-04 1.42480114e-04 1.39796988e-04 1.37531511e-04
 1.37405573e-04 1.36193514e-04 1.35348297e-04 1.34942594e-04
 1.33386752e-04 1.32698208e-04 1.30939541e-04 1.30626558e-04
 1.29794153e-04 1.28516421e-04 1.27645103e-04 1.27009714e-04
 1.26169516e-04 1.24142148e-04 1.23952145e-04 1.23090174e-04
 1.22125656e-04 1.21644861e-04 1.19118031e-04 1.18742114e-04
 1.17710049e-04 1.16952561e-04 1.15730910e-04 1.14859115e-04
 1.14205443e-04 1.13226046e-04 1.11808090e-04 1.10294181e-04
 1.09549624e-04 1.08538731e-04 1.08225994e-04 1.07316513e-04
 1.06798747e-04 1.04967676e-04 1.04828559e-04 1.02903894e-04
 1.01653558e-04 1.01411403e-04 1.00960463e-04 9.85747690e-05
 9.84245139e-05 9.78532935e-05 9.75656815e-05 9.69059492e-05
 9.50200889e-05 9.45012935e-05 9.31820460e-05 9.22634842e-05
 9.14667021e-05 8.99545001e-05 8.90336567e-05 8.83631530e-05
 8.81336699e-05 8.75371233e-05 8.67586098e-05 8.57430420e-05
 8.50970260e-05 8.35766080e-05 8.32330663e-05 8.21238235e-05
 8.14231172e-05 8.13076102e-05 8.07384988e-05 8.04961536e-05
 7.98642480e-05 7.88865234e-05 7.81980323e-05 7.67646478e-05
 7.62838305e-05 7.60239115e-05 7.55142450e-05 7.41224076e-05
 7.35136646e-05 7.28558367e-05 7.20679962e-05 7.16472308e-05
 7.09332955e-05 7.07883240e-05 7.03454440e-05 6.92632893e-05
 6.90546690e-05 6.77856383e-05 6.68483802e-05 6.66455463e-05
 6.62889196e-05 6.47686422e-05 6.42365422e-05 6.40057772e-05
 6.29855705e-05 6.23013637e-05 6.14695683e-05 6.03578550e-05
 6.01159338e-05 5.95779919e-05 5.94267186e-05 5.83761020e-05
 5.74355934e-05 5.58098783e-05 5.54127798e-05 5.49369041e-05
 5.45716385e-05 5.40374573e-05 5.34850842e-05 5.31568603e-05
 5.23570621e-05 5.11997553e-05 5.09507143e-05 5.05055450e-05
 5.00185230e-05 4.95112111e-05 4.93448502e-05 4.81597583e-05
 4.76888009e-05 4.67232851e-05 4.62826953e-05 4.58624926e-05
 4.48913236e-05 4.46309205e-05 4.34878160e-05 4.31946963e-05
 4.25389394e-05 4.19323269e-05 4.15832190e-05 4.12054430e-05
 4.07166135e-05 4.02543471e-05 3.97580503e-05 3.92507438e-05
 3.82590389e-05 3.81130822e-05 3.76803640e-05 3.74242211e-05
 3.69747753e-05 3.66531035e-05 3.59809811e-05 3.51504376e-05
 3.49405193e-05 3.47213949e-05 3.41366129e-05 3.38083053e-05
 3.30654613e-05 3.26278656e-05 3.21459439e-05 3.19012640e-05
 3.13191694e-05 3.07613332e-05 3.00219760e-05 2.99591612e-05
 2.94063992e-05 2.92491909e-05 2.89743816e-05 2.84058955e-05
 2.79720864e-05 2.74821439e-05 2.72096995e-05 2.67350203e-05
 2.63331358e-05 2.59144913e-05 2.58735750e-05 2.54731199e-05
 2.51773851e-05 2.50524363e-05 2.44813402e-05 2.40705039e-05
 2.39874570e-05 2.34633543e-05 2.29477584e-05 2.25093611e-05
 2.22155074e-05 2.20790247e-05 2.17591048e-05 2.16204297e-05
 2.09121899e-05 2.05392893e-05 2.03250283e-05 2.01961925e-05
 1.93426285e-05 1.91686034e-05 1.87001598e-05 1.84466937e-05
 1.83406764e-05 1.78923026e-05 1.75606832e-05 1.73474446e-05
 1.72135691e-05 1.70523572e-05 1.69307127e-05 1.66227203e-05
 1.60851859e-05 1.58323274e-05 1.56102455e-05 1.52779066e-05
 1.50378730e-05 1.46476501e-05 1.44700666e-05 1.42400809e-05
 1.40848570e-05 1.38950226e-05 1.37986828e-05 1.32756252e-05
 1.32587055e-05 1.30379892e-05 1.28746568e-05 1.25425461e-05
 1.24703562e-05 1.22614736e-05 1.20926196e-05 1.18893911e-05
 1.15410491e-05 1.14312145e-05 1.11562329e-05 1.09174748e-05
 1.07658086e-05 1.06691380e-05 1.03051144e-05 1.00914783e-05
 1.00308370e-05 1.00105601e-05 9.85925181e-06 9.77759963e-06
 9.42679737e-06 9.33693994e-06 9.11459734e-06 8.96814466e-06
 8.68713036e-06 8.63229224e-06 8.52644617e-06 8.48286354e-06
 8.29080342e-06 8.19835206e-06 7.91258013e-06 7.76493607e-06
 7.63260892e-06 7.43546425e-06 7.07462662e-06 6.98711605e-06
 6.88829986e-06 6.72560060e-06 6.66911051e-06 6.52727390e-06
 6.41030577e-06 6.23340512e-06 6.11257093e-06 5.97925248e-06
 5.96601846e-06 5.89562220e-06 5.68216483e-06 5.58898373e-06
 5.41786022e-06 5.38145306e-06 5.34834250e-06 5.28383801e-06
 5.12427048e-06 5.02975476e-06 4.95783261e-06 4.93473855e-06
 4.88150956e-06 4.77992755e-06 4.70717199e-06 4.40771325e-06
 4.27440899e-06 4.16876694e-06 4.05280868e-06 4.01325067e-06
 3.88186425e-06 3.81966994e-06 3.71032307e-06 3.63065185e-06
 3.55203061e-06 3.47632242e-06 3.39332925e-06 3.35410784e-06
 3.28931809e-06 3.23147335e-06 3.11392115e-06 3.06018982e-06
 3.03378492e-06 2.96781626e-06 2.81789482e-06 2.68666764e-06
 2.53853728e-06 2.39661656e-06 2.35842783e-06 2.23394153e-06
 2.18138955e-06 2.10511382e-06 2.08287706e-06 1.96971540e-06
 1.92647522e-06 1.89934432e-06 1.78642586e-06 1.70248716e-06
 1.66650894e-06 1.63804545e-06 1.51781612e-06 1.39373417e-06
 1.33832668e-06 1.24476222e-06 1.21730908e-06 1.18446640e-06
 1.15560785e-06 1.01494135e-06 9.85391689e-07 9.22558126e-07
 8.60985355e-07 8.09482328e-07 7.91277283e-07 7.64520475e-07
 7.34348708e-07 6.09812977e-07 5.59687378e-07 5.12546038e-07
 4.61087216e-07 4.23521135e-07 4.09430003e-07 4.02353357e-07
 3.93384177e-07 3.72248264e-07 3.48924231e-07 3.37096656e-07
 3.11758092e-07 1.56647635e-07 1.33880106e-07 9.00109234e-08
 8.78809905e-08 5.23582187e-08 9.33887816e-09 4.25784769e-10
 2.44230025e-32 1.23966762e-32 1.10048686e-32 9.75635234e-33
 7.39449157e-33 6.41075181e-33 5.86377201e-33 4.53084933e-33
 4.15305497e-33 3.66377742e-33 3.01020083e-33 2.54292667e-33
 2.40526295e-33 1.90295864e-33 1.70136720e-33 1.69440330e-33
 1.32362540e-33 1.18413494e-33 1.08471904e-33 8.16043969e-34
 7.66312636e-34 5.80920191e-34 5.50721133e-34 5.49776984e-34
 5.02864392e-34 4.91223899e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 4.47586095e-34 4.47586095e-34 4.47586095e-34
 4.47586095e-34 3.41433752e-34 3.05029223e-34 1.69181151e-34
 1.66196005e-34 8.33750200e-35 6.22730721e-35 8.66877011e-36]
[0.12038313 0.2060633  0.28280404 0.34682703 0.38850281 0.42644059
 0.46063385 0.49336481 0.52070424 0.54547881 0.56809696 0.58885336
 0.60829449 0.62495741 0.63930363 0.65290793 0.66494819 0.67655055
 0.68762189 0.69715951 0.70628762 0.71530001 0.72370024 0.7320656
 0.73990329 0.7470166  0.75390282 0.76036826 0.7665979  0.77267255
 0.77826933 0.78366639 0.7888975  0.79381542 0.79855369 0.80317495
 0.80755726 0.81180596 0.81576308 0.81963974 0.82337856 0.82701244
 0.83039464 0.83376023 0.83703976 0.84019787 0.84320163 0.846107
 0.84891583 0.85161618 0.8542074  0.85669278 0.85913083 0.86153742
 0.86382746 0.86608953 0.86832248 0.87051354 0.87261743 0.87464354
 0.87662512 0.87857471 0.88041178 0.88220208 0.88397109 0.88571319
 0.88741194 0.88906255 0.89066661 0.89221572 0.89371191 0.89517427
 0.89663381 0.89804505 0.89944953 0.90079679 0.90213098 0.90342593
 0.90470302 0.90596265 0.90718502 0.90839198 0.90956921 0.9107326
 0.9118741  0.9129773  0.91404982 0.91509502 0.9161359  0.9171627
 0.9181728  0.91915357 0.92011657 0.92104919 0.92197999 0.92289472
 0.92380023 0.92469258 0.92557692 0.92645045 0.92731351 0.92816366
 0.92899605 0.92982165 0.9306369  0.93144493 0.93223623 0.93302164
 0.93379025 0.93455325 0.93530553 0.93604053 0.9367611  0.93746758
 0.93816485 0.93884644 0.93952435 0.9401848  0.94083373 0.9414753
 0.9421109  0.94273951 0.94335707 0.94396835 0.94457891 0.94517309
 0.94576483 0.94634432 0.94690893 0.94747011 0.94802312 0.94857112
 0.94911    0.94964335 0.95016903 0.95068957 0.95119934 0.95170674
 0.95220383 0.95269683 0.95318666 0.95367182 0.95415103 0.95462408
 0.95509211 0.95555126 0.95600859 0.95646314 0.95691095 0.95735619
 0.95778974 0.95821711 0.95864157 0.95906305 0.9594785  0.95988996
 0.96029769 0.96070187 0.96109444 0.96148355 0.96187122 0.96225691
 0.96263981 0.96301148 0.96338058 0.96374482 0.9641048  0.96445778
 0.96480922 0.96515999 0.96550767 0.9658539  0.96619538 0.96652803
 0.96685779 0.96718629 0.96751025 0.96783337 0.9681533  0.96847083
 0.96878287 0.96909308 0.96939942 0.9697008  0.97000024 0.97029589
 0.9705892  0.97088044 0.97116812 0.97145419 0.9717364  0.97201554
 0.97228922 0.97255988 0.97282975 0.97309708 0.97335913 0.97361773
 0.97387454 0.97412969 0.97438303 0.97463425 0.97488251 0.97513014
 0.97537681 0.97561839 0.9758588  0.97609649 0.97632993 0.97656153
 0.9767921  0.97701955 0.97724669 0.9774701  0.97769314 0.97791281
 0.97813084 0.97834717 0.97856184 0.97877488 0.97898568 0.97919448
 0.97940197 0.97960826 0.97981269 0.98001301 0.98021255 0.98041027
 0.98060525 0.98079871 0.98098816 0.98117676 0.98136392 0.98155023
 0.98173445 0.98191703 0.98209804 0.98227753 0.98245574 0.98263239
 0.98280826 0.98298232 0.98315502 0.98332601 0.98349597 0.9836633
 0.98383028 0.98399655 0.98416044 0.98432394 0.9844868  0.98464784
 0.98480519 0.9849617  0.98511629 0.98527037 0.98542306 0.98557439
 0.98572535 0.98587481 0.9860235  0.98617    0.9863151  0.98645905
 0.98660237 0.98674485 0.98688465 0.98702218 0.98715959 0.98729578
 0.98743113 0.98756607 0.98769946 0.98783216 0.9879631  0.98809372
 0.98822352 0.98835203 0.98847968 0.98860669 0.98873286 0.988857
 0.98898095 0.98910404 0.98922617 0.98934781 0.98946693 0.98958567
 0.98970338 0.98982033 0.98993607 0.99005092 0.99016513 0.99027836
 0.99039016 0.99050046 0.99061001 0.99071855 0.99082677 0.99093409
 0.99104089 0.99114586 0.99125068 0.99135359 0.99145524 0.99155665
 0.99165761 0.99175619 0.99185461 0.99195247 0.99205003 0.99214694
 0.99224196 0.99233646 0.99242964 0.9925219  0.99261337 0.99270333
 0.99279236 0.99288072 0.99296886 0.99305639 0.99314315 0.9932289
 0.99331399 0.99339757 0.9934808  0.99356293 0.99364435 0.99372566
 0.9938064  0.99388689 0.99396676 0.99404564 0.99412384 0.9942006
 0.99427689 0.99435291 0.99442843 0.99450255 0.99457606 0.99464892
 0.99472099 0.99479263 0.99486357 0.99493436 0.9950047  0.99507396
 0.99514302 0.9952108  0.99527765 0.9953443  0.99541059 0.99547536
 0.99553959 0.9956036  0.99566658 0.99572889 0.99579035 0.99585071
 0.99591083 0.99597041 0.99602983 0.99608821 0.99614565 0.99620145
 0.99625687 0.9963118  0.99636638 0.99642041 0.9964739  0.99652706
 0.99657941 0.99663061 0.99668156 0.99673207 0.99678209 0.9968316
 0.99688094 0.9969291  0.99697679 0.99702352 0.9970698  0.99711566
 0.99716055 0.99720518 0.99724867 0.99729187 0.9973344  0.99737634
 0.99741792 0.99745913 0.99749984 0.9975401  0.99757985 0.9976191
 0.99765736 0.99769548 0.99773316 0.99777058 0.99780756 0.99784421
 0.99788019 0.99791534 0.99795028 0.997985   0.99801914 0.99805295
 0.99808601 0.99811864 0.99815079 0.99818269 0.99821401 0.99824477
 0.99827479 0.99830475 0.99833416 0.99836341 0.99839238 0.99842079
 0.99844876 0.99847624 0.99850345 0.99853018 0.99855652 0.99858243
 0.99860831 0.99863378 0.99865896 0.99868401 0.99870849 0.99873256
 0.99875655 0.99878001 0.99880296 0.99882547 0.99884768 0.99886976
 0.99889152 0.99891314 0.99893405 0.99895459 0.99897492 0.99899512
 0.99901446 0.99903363 0.99905233 0.99907077 0.99908911 0.99910701
 0.99912457 0.99914191 0.99915913 0.99917618 0.99919311 0.99920973
 0.99922582 0.99924165 0.99925726 0.99927254 0.99928758 0.99930223
 0.9993167  0.99933094 0.99934502 0.99935892 0.99937271 0.99938599
 0.99939925 0.99941229 0.99942516 0.9994377  0.99945017 0.99946244
 0.99947453 0.99948642 0.99949796 0.99950939 0.99952055 0.99953146
 0.99954223 0.9995529  0.9995632  0.99957329 0.99958333 0.99959334
 0.9996032  0.99961297 0.9996224  0.99963174 0.99964085 0.99964982
 0.99965851 0.99966714 0.99967567 0.99968415 0.99969244 0.99970064
 0.99970855 0.99971631 0.99972395 0.99973138 0.99973846 0.99974544
 0.99975233 0.99975906 0.99976573 0.99977225 0.99977867 0.9997849
 0.99979101 0.99979699 0.99980296 0.99980885 0.99981453 0.99982012
 0.99982554 0.99983092 0.99983627 0.99984155 0.99984668 0.99985171
 0.99985667 0.9998616  0.99986648 0.99987126 0.99987597 0.99988038
 0.99988465 0.99988882 0.99989287 0.99989689 0.99990077 0.99990459
 0.9999083  0.99991193 0.99991548 0.99991896 0.99992235 0.99992571
 0.99992899 0.99993223 0.99993534 0.9999384  0.99994143 0.9999444
 0.99994722 0.99994991 0.99995244 0.99995484 0.9999572  0.99995943
 0.99996162 0.99996372 0.9999658  0.99996777 0.9999697  0.9999716
 0.99997339 0.99997509 0.99997675 0.99997839 0.99997991 0.9999813
 0.99998264 0.99998389 0.9999851  0.99998629 0.99998744 0.99998846
 0.99998944 0.99999037 0.99999123 0.99999204 0.99999283 0.99999359
 0.99999433 0.99999494 0.9999955  0.99999601 0.99999647 0.99999689
 0.9999973  0.99999771 0.9999981  0.99999847 0.99999882 0.99999916
 0.99999947 0.99999963 0.99999976 0.99999985 0.99999994 0.99999999
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.        ]
In [67]:
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.singular_values_ )+1),myPCA.singular_values_ ,alpha=0.8,marker='.');
#La nueva base son los vectores propios de la matriz de covarianza.
y_label = plt.ylabel('Vectores propios');
x_label = plt.xlabel('Componentes');
plt.title('Scree plot');
In [68]:
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
         np.cumsum(myPCA.explained_variance_ratio_),
         c='red',marker='.',
         label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
Out[68]:
<matplotlib.lines.Line2D at 0x147085a20>

Podemos ver que usando MinMaxScaler() a la matriz original obtenemos que con alrededor de 50 podemos explicar el 85% de la variancia de los datos, cuando usando StandardScaler() solo podiamos hacerlo con un poco más de 100 componentes.

In [69]:
transformed_train = myPCA.transform(X_train_standarized[X_train_copia.columns])
transformed_train

X_train_standarized[['PC1','PC2','PC3']] = transformed_train[:,:3]

fig = plt.figure(figsize=(8,8))
_ = sns.scatterplot(x='PC1', y='PC2', data=X_train_standarized, hue=y_train, palette='tab10')

Podemos apreciar una mejor separabilidad de las clases, sobretodo para la clase del 7 aunque podemos seguir viendo que para la clase del 4 y del 9 el conjunto de datos parece aún agruparse.

In [70]:
import plotly.express as px

fig = px.scatter_3d(X_train_standarized, x='PC1', y='PC2', z='PC3',color=y_train)
fig.show()
In [71]:
from sklearn.manifold import TSNE

transformed_train = TSNE(n_components=2, perplexity=10, n_iter=2000, init='pca').fit_transform(X_train_standarized[data_columns])

fig = plt.figure(figsize=(8,8))
sns.scatterplot(x=transformed_train[:,0], y=transformed_train[:,1], hue=y_train, palette='tab10');

Vemos que obtenemos una mejor visión de separabilidad de las clases si lo comparamos con el primer plot de t-SNE que hemos realizado usando la matriz de datos original. Este es mejor, ya que parece que tenemos los puntos mas juntos con puntos de su misma clase y no se nos han creado tantos conjuntos pequeños de puntos de la misma clase.

Con respecto al segundo plot de t-SNE no podemos apreciar casi distinciones, además contamos con un componente random a la hora de realizar este método

Aplicación del PCA con el conjunto de datos binarizado usando MinMaxScaler()¶

Veremos que tenemos el mismo resultado que hemos obtenido cuando hemos mostrado el PCA con los datos binarizados, puesto que la transformación será la misma usando StandardScaler() que MinMax() debido a la naturaleza de los datos binarizados.

In [72]:
X_train_bin = Binarizer(threshold=0.5).transform(X_train_copia)
X_test_bin  = Binarizer(threshold=0.5).transform(X_test_copia)

X_train_bin.shape, X_test_bin.shape
Out[72]:
((4514, 784), (755, 784))
In [73]:
X_train_bin = pd.DataFrame(X_train_bin)
X_test_bin = pd.DataFrame(X_test_bin)

X_train_bin.shape, X_test_bin.shape

X_train_bin_2 = X_train_bin.copy()
X_test_bin_2 = X_test_bin.copy()
In [74]:
X_train_standarized_bin = X_train_bin_2.copy()
scaler = MinMaxScaler()

X_train_standarized_bin[data_columns] = scaler.fit_transform(X_train_bin_2[data_columns])
X_train_standarized_bin.describe().T

X_test_standarized_bin = X_test_bin_2.copy()

X_test_standarized_bin[data_columns] = scaler.transform(X_test_bin_2[data_columns])
X_test_standarized_bin.describe().T
Out[74]:
count mean std min 25% 50% 75% max
0 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
4 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
... ... ... ... ... ... ... ... ...
779 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
780 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
781 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
782 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
783 755.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

784 rows × 8 columns

In [75]:
myPCA = PCA().fit(X_train_standarized_bin[data_columns]);

#PCA.explained_variance_ratio_ para comprender qué porcentaje de varianza explican los datos
print(myPCA.explained_variance_ratio_)
print(myPCA.explained_variance_ratio_.cumsum())
[9.86798398e-02 7.04159474e-02 6.36020040e-02 5.31339161e-02
 3.52681806e-02 3.22573620e-02 2.92687983e-02 2.81081504e-02
 2.39018796e-02 2.16883416e-02 2.00622161e-02 1.80625948e-02
 1.71227051e-02 1.48541649e-02 1.27857931e-02 1.22601056e-02
 1.08417855e-02 1.04941546e-02 1.01347878e-02 8.92418783e-03
 8.42672796e-03 8.39248180e-03 7.92445291e-03 7.67216304e-03
 7.26547858e-03 6.76383979e-03 6.59597574e-03 6.32187391e-03
 5.93263536e-03 5.90091617e-03 5.56263645e-03 5.30204256e-03
 5.12971018e-03 4.85244121e-03 4.75997704e-03 4.61781320e-03
 4.41360918e-03 4.37273155e-03 4.06526852e-03 3.95588871e-03
 3.81041156e-03 3.74375705e-03 3.66060359e-03 3.52344667e-03
 3.49995732e-03 3.31201567e-03 3.15033722e-03 3.11434482e-03
 3.02280040e-03 2.98051696e-03 2.84618846e-03 2.78909934e-03
 2.74665561e-03 2.71329826e-03 2.61310964e-03 2.59562078e-03
 2.55321005e-03 2.52241692e-03 2.47551531e-03 2.41137283e-03
 2.37521385e-03 2.28800414e-03 2.24981956e-03 2.19382900e-03
 2.16139375e-03 2.14203895e-03 2.11876075e-03 2.09488626e-03
 2.04760584e-03 2.02373766e-03 1.98127750e-03 1.92705662e-03
 1.90018920e-03 1.86134698e-03 1.85379294e-03 1.83663645e-03
 1.82205620e-03 1.78287565e-03 1.77113778e-03 1.74660904e-03
 1.72013074e-03 1.70774423e-03 1.67188255e-03 1.64253119e-03
 1.62566053e-03 1.60717981e-03 1.58540266e-03 1.57384066e-03
 1.56113555e-03 1.54271278e-03 1.52758166e-03 1.50891465e-03
 1.47906087e-03 1.45207754e-03 1.42431058e-03 1.41221494e-03
 1.40669552e-03 1.38816917e-03 1.36743791e-03 1.35985192e-03
 1.34537646e-03 1.33413717e-03 1.31796140e-03 1.31145211e-03
 1.30437260e-03 1.29486502e-03 1.28165518e-03 1.27678099e-03
 1.25415287e-03 1.23507083e-03 1.22088650e-03 1.20770298e-03
 1.20491738e-03 1.20306865e-03 1.18048109e-03 1.17629956e-03
 1.16734655e-03 1.15378401e-03 1.15194593e-03 1.13981288e-03
 1.13078954e-03 1.11674440e-03 1.11069671e-03 1.10134205e-03
 1.08972615e-03 1.07777265e-03 1.07066318e-03 1.06349559e-03
 1.05719198e-03 1.04944405e-03 1.04042456e-03 1.03573069e-03
 1.03074442e-03 1.02091352e-03 1.01608538e-03 1.00900307e-03
 9.98746368e-04 9.88304753e-04 9.84607681e-04 9.71511141e-04
 9.62230990e-04 9.58754218e-04 9.55635643e-04 9.47094852e-04
 9.41108245e-04 9.35137075e-04 9.25800262e-04 9.21307613e-04
 9.09499199e-04 8.97888146e-04 8.94400181e-04 8.87746524e-04
 8.83773471e-04 8.76684104e-04 8.68235669e-04 8.62673790e-04
 8.55291458e-04 8.50009733e-04 8.45057473e-04 8.41253158e-04
 8.31717885e-04 8.27100045e-04 8.25614454e-04 8.15480878e-04
 8.14286513e-04 8.05906104e-04 8.00796688e-04 7.96109391e-04
 7.94519796e-04 7.85594602e-04 7.82977209e-04 7.79700148e-04
 7.76711828e-04 7.65885923e-04 7.63033953e-04 7.58816942e-04
 7.54659364e-04 7.44889572e-04 7.37053808e-04 7.33610340e-04
 7.30261998e-04 7.25011430e-04 7.20200103e-04 7.15815206e-04
 7.08858203e-04 7.05746267e-04 7.03524279e-04 7.00395356e-04
 6.95550428e-04 6.91398213e-04 6.87295558e-04 6.83692415e-04
 6.76950689e-04 6.69072701e-04 6.65939212e-04 6.62761454e-04
 6.60020653e-04 6.59435212e-04 6.46938361e-04 6.45511470e-04
 6.43407399e-04 6.36852592e-04 6.32326600e-04 6.29064424e-04
 6.24932086e-04 6.21071727e-04 6.14941311e-04 6.12668854e-04
 6.10835455e-04 6.03096616e-04 5.99910316e-04 5.96380621e-04
 5.93975497e-04 5.90131016e-04 5.85771507e-04 5.80926022e-04
 5.75120492e-04 5.71561237e-04 5.67441902e-04 5.61100253e-04
 5.57855464e-04 5.53285354e-04 5.49820453e-04 5.47781751e-04
 5.42649063e-04 5.38337605e-04 5.35100002e-04 5.31700401e-04
 5.22781947e-04 5.21881014e-04 5.14738914e-04 5.14217712e-04
 5.09661825e-04 5.03586191e-04 4.99509339e-04 4.94909433e-04
 4.90163577e-04 4.88464119e-04 4.84587062e-04 4.82223654e-04
 4.80513044e-04 4.76291574e-04 4.69242905e-04 4.65049603e-04
 4.62839502e-04 4.60928268e-04 4.58550521e-04 4.52943767e-04
 4.49041719e-04 4.45190543e-04 4.41593561e-04 4.41096751e-04
 4.38877024e-04 4.34621049e-04 4.31043083e-04 4.26431344e-04
 4.22481408e-04 4.20759511e-04 4.19086833e-04 4.14392809e-04
 4.12367475e-04 4.11452647e-04 4.02959512e-04 4.01350053e-04
 3.99864877e-04 3.97326418e-04 3.93804489e-04 3.89925146e-04
 3.86694479e-04 3.82654222e-04 3.80257242e-04 3.76516964e-04
 3.72924242e-04 3.70684400e-04 3.68154395e-04 3.63851409e-04
 3.61565063e-04 3.59963610e-04 3.55215555e-04 3.51211804e-04
 3.46752540e-04 3.43744340e-04 3.40998336e-04 3.39686347e-04
 3.31673591e-04 3.29525289e-04 3.25993664e-04 3.24733500e-04
 3.22226523e-04 3.20443816e-04 3.16299551e-04 3.14485477e-04
 3.08342379e-04 3.04034344e-04 2.99029148e-04 2.97796746e-04
 2.96375830e-04 2.92736001e-04 2.91812454e-04 2.86393214e-04
 2.84505154e-04 2.80889512e-04 2.78772619e-04 2.76958587e-04
 2.74852838e-04 2.72564847e-04 2.68150468e-04 2.63407197e-04
 2.60589752e-04 2.57453959e-04 2.56233766e-04 2.53213954e-04
 2.50362918e-04 2.46603739e-04 2.43228465e-04 2.41414425e-04
 2.39541979e-04 2.36901331e-04 2.32609357e-04 2.31961344e-04
 2.28438285e-04 2.24517386e-04 2.22968118e-04 2.18678509e-04
 2.14969009e-04 2.14144381e-04 2.11991428e-04 2.09808964e-04
 2.06169803e-04 2.03263299e-04 2.00161172e-04 1.97690155e-04
 1.96313561e-04 1.92906123e-04 1.91316689e-04 1.89201981e-04
 1.86818593e-04 1.83459887e-04 1.82419298e-04 1.80549411e-04
 1.77993216e-04 1.75093863e-04 1.70763435e-04 1.69372391e-04
 1.66622832e-04 1.61761122e-04 1.61115293e-04 1.59300549e-04
 1.57434929e-04 1.55936605e-04 1.55273682e-04 1.54205401e-04
 1.52421389e-04 1.50806017e-04 1.48238961e-04 1.46391244e-04
 1.44028162e-04 1.42212403e-04 1.41223272e-04 1.37246426e-04
 1.36308794e-04 1.34671823e-04 1.33080656e-04 1.32465076e-04
 1.30329486e-04 1.26506833e-04 1.24942744e-04 1.23617101e-04
 1.22373191e-04 1.21344186e-04 1.18966008e-04 1.17825607e-04
 1.16129981e-04 1.13816623e-04 1.12067828e-04 1.11389139e-04
 1.10624665e-04 1.09465208e-04 1.08523646e-04 1.05962625e-04
 1.04902058e-04 1.03308464e-04 1.00360259e-04 9.96922125e-05
 9.81542680e-05 9.65107590e-05 9.63001216e-05 9.51725187e-05
 9.36350641e-05 9.02760938e-05 9.01417386e-05 8.96320984e-05
 8.71310962e-05 8.67546496e-05 8.51812901e-05 8.26372461e-05
 8.15129991e-05 8.06371423e-05 7.85563545e-05 7.72131947e-05
 7.70403713e-05 7.63940619e-05 7.46662773e-05 7.20446998e-05
 7.02455412e-05 6.93631234e-05 6.86414049e-05 6.73050980e-05
 6.63883691e-05 6.51019853e-05 6.42237218e-05 6.35940616e-05
 6.27659536e-05 6.22173437e-05 6.14951949e-05 5.97647363e-05
 5.91207376e-05 5.84643300e-05 5.74801057e-05 5.67875485e-05
 5.63392551e-05 5.50444872e-05 5.41714096e-05 5.26620173e-05
 5.19051757e-05 5.17649695e-05 5.02842806e-05 4.98319165e-05
 4.95129501e-05 4.89616906e-05 4.72960705e-05 4.66765970e-05
 4.58199825e-05 4.46250585e-05 4.44306841e-05 4.28951952e-05
 4.21669020e-05 4.20280791e-05 3.97174154e-05 3.96513451e-05
 3.83120521e-05 3.80815504e-05 3.71227003e-05 3.67371472e-05
 3.65751940e-05 3.55179813e-05 3.51512148e-05 3.47859768e-05
 3.42312849e-05 3.35412594e-05 3.32326056e-05 3.22203835e-05
 3.21044284e-05 3.15462175e-05 3.10160189e-05 3.04694549e-05
 2.97913575e-05 2.94674543e-05 2.91453011e-05 2.78808043e-05
 2.77236068e-05 2.72665793e-05 2.68379427e-05 2.62597852e-05
 2.55039548e-05 2.51671971e-05 2.47633887e-05 2.40094533e-05
 2.34012481e-05 2.27479373e-05 2.26812987e-05 2.20862148e-05
 2.11492952e-05 2.05902495e-05 2.01656202e-05 2.01195572e-05
 1.94797566e-05 1.93270485e-05 1.87820724e-05 1.86516371e-05
 1.84468542e-05 1.79176149e-05 1.76865882e-05 1.66458325e-05
 1.61443651e-05 1.59074920e-05 1.52864376e-05 1.51998708e-05
 1.51827973e-05 1.48990285e-05 1.46495099e-05 1.41370327e-05
 1.39017144e-05 1.38153532e-05 1.30943254e-05 1.27843340e-05
 1.22953110e-05 1.18195252e-05 1.15811754e-05 1.13010252e-05
 1.09883982e-05 1.04959232e-05 1.04750745e-05 1.01876689e-05
 9.94403235e-06 9.70976490e-06 9.43689191e-06 9.33290900e-06
 9.10932240e-06 8.78696455e-06 8.69260515e-06 8.33673784e-06
 8.21084539e-06 8.13849900e-06 7.95688455e-06 7.65345549e-06
 7.18026630e-06 6.91811800e-06 6.75946574e-06 6.67847134e-06
 6.60827899e-06 6.31919071e-06 5.95416943e-06 5.74707056e-06
 5.56694711e-06 5.39032235e-06 5.21366606e-06 5.19893354e-06
 4.95223472e-06 4.76708093e-06 4.50989051e-06 4.46797500e-06
 4.26204159e-06 4.18115481e-06 4.15701256e-06 3.98835822e-06
 3.77539879e-06 3.56581890e-06 3.53663832e-06 3.21958550e-06
 3.10378880e-06 3.05684819e-06 3.02621799e-06 2.73889694e-06
 2.69730203e-06 2.66023779e-06 2.51080690e-06 2.45319987e-06
 2.38420955e-06 2.25307503e-06 2.03850701e-06 1.96147857e-06
 1.84674802e-06 1.60566854e-06 1.42747044e-06 1.35808602e-06
 1.23842396e-06 1.21138234e-06 1.15899041e-06 1.12118114e-06
 9.64891887e-07 8.53512378e-07 8.32853898e-07 7.75026313e-07
 7.63510748e-07 6.22234458e-07 4.24219140e-07 3.45987888e-07
 3.28079315e-07 1.96049565e-32 6.47531246e-33 5.16192985e-33
 4.68768237e-33 4.06556242e-33 4.01784362e-33 3.66222022e-33
 3.09073295e-33 2.61804802e-33 2.47990181e-33 2.37282080e-33
 2.10301805e-33 1.94897094e-33 1.79492023e-33 1.77076194e-33
 1.51853461e-33 1.45629031e-33 1.23013282e-33 1.20454342e-33
 9.80313193e-34 7.00500055e-34 6.84576105e-34 6.56904073e-34
 4.44176191e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 4.19092174e-34
 4.19092174e-34 4.19092174e-34 4.19092174e-34 3.35166108e-34
 3.11518758e-34 2.98493256e-34 2.73285252e-34 1.50036002e-34
 8.98153107e-35 5.87713160e-35 2.79741894e-35 4.23372289e-36]
[0.09867984 0.16909579 0.23269779 0.28583171 0.32109989 0.35335725
 0.38262605 0.4107342  0.43463608 0.45632442 0.47638664 0.49444923
 0.51157194 0.5264261  0.53921189 0.551472   0.56231378 0.57280794
 0.58294273 0.59186692 0.60029364 0.60868612 0.61661058 0.62428274
 0.63154822 0.63831206 0.64490803 0.65122991 0.65716254 0.66306346
 0.6686261  0.67392814 0.67905785 0.68391029 0.68867027 0.69328808
 0.69770169 0.70207442 0.70613969 0.71009558 0.71390599 0.71764975
 0.72131035 0.7248338  0.72833376 0.73164577 0.73479611 0.73791045
 0.74093325 0.74391377 0.74675996 0.74954906 0.75229571 0.75500901
 0.75762212 0.76021774 0.76277095 0.76529337 0.76776888 0.77018026
 0.77255547 0.77484348 0.77709329 0.77928712 0.78144852 0.78359056
 0.78570932 0.7878042  0.78985181 0.79187555 0.79385682 0.79578388
 0.79768407 0.79954542 0.80139921 0.80323585 0.8050579  0.80684078
 0.80861192 0.81035853 0.81207866 0.8137864  0.81545828 0.81710081
 0.81872647 0.82033365 0.82191906 0.8234929  0.82505403 0.82659675
 0.82812433 0.82963324 0.8311123  0.83256438 0.83398869 0.83540091
 0.8368076  0.83819577 0.83956321 0.84092306 0.84226844 0.84360257
 0.84492054 0.84623199 0.84753636 0.84883123 0.85011288 0.85138966
 0.85264381 0.85387889 0.85509977 0.85630748 0.85751239 0.85871546
 0.85989594 0.86107224 0.86223959 0.86339337 0.86454532 0.86568513
 0.86681592 0.86793267 0.86904336 0.8701447  0.87123443 0.8723122
 0.87338287 0.87444636 0.87550355 0.876553   0.87759342 0.87862915
 0.8796599  0.88068081 0.8816969  0.8827059  0.88370465 0.88469295
 0.88567756 0.88664907 0.8876113  0.88857005 0.88952569 0.89047278
 0.89141389 0.89234903 0.89327483 0.89419614 0.89510564 0.89600353
 0.89689793 0.89778567 0.89866945 0.89954613 0.90041437 0.90127704
 0.90213233 0.90298234 0.9038274  0.90466865 0.90550037 0.90632747
 0.90715308 0.90796856 0.90878285 0.90958876 0.91038955 0.91118566
 0.91198018 0.91276578 0.91354875 0.91432845 0.91510517 0.91587105
 0.91663409 0.9173929  0.91814756 0.91889245 0.91962951 0.92036312
 0.92109338 0.92181839 0.92253859 0.92325441 0.92396326 0.92466901
 0.92537253 0.92607293 0.92676848 0.92745988 0.92814717 0.92883087
 0.92950782 0.93017689 0.93084283 0.93150559 0.93216561 0.93282505
 0.93347198 0.9341175  0.9347609  0.93539776 0.93603008 0.93665915
 0.93728408 0.93790515 0.93852009 0.93913276 0.9397436  0.94034669
 0.9409466  0.94154298 0.94213696 0.94272709 0.94331286 0.94389379
 0.94446891 0.94504047 0.94560791 0.94616901 0.94672687 0.94728015
 0.94782997 0.94837775 0.9489204  0.94945874 0.94999384 0.95052554
 0.95104832 0.9515702  0.95208494 0.95259916 0.95310882 0.95361241
 0.95411192 0.95460683 0.95509699 0.95558546 0.95607004 0.95655227
 0.95703278 0.95750907 0.95797831 0.95844336 0.9589062  0.95936713
 0.95982568 0.96027863 0.96072767 0.96117286 0.96161445 0.96205555
 0.96249443 0.96292905 0.96336009 0.96378652 0.964209   0.96462976
 0.96504885 0.96546324 0.96587561 0.96628706 0.96669002 0.96709137
 0.96749124 0.96788856 0.96828237 0.96867229 0.96905899 0.96944164
 0.9698219  0.97019841 0.97057134 0.97094202 0.97131018 0.97167403
 0.97203559 0.97239556 0.97275077 0.97310199 0.97344874 0.97379248
 0.97413348 0.97447317 0.97480484 0.97513437 0.97546036 0.97578509
 0.97610732 0.97642776 0.97674406 0.97705855 0.97736689 0.97767092
 0.97796995 0.97826775 0.97856413 0.97885686 0.97914868 0.97943507
 0.97971957 0.98000046 0.98027924 0.98055619 0.98083105 0.98110361
 0.98137176 0.98163517 0.98189576 0.98215321 0.98240945 0.98266266
 0.98291302 0.98315963 0.98340286 0.98364427 0.98388381 0.98412071
 0.98435332 0.98458528 0.98481372 0.98503824 0.98526121 0.98547989
 0.98569486 0.985909   0.98612099 0.9863308  0.98653697 0.98674023
 0.98694039 0.98713808 0.9873344  0.9875273  0.98771862 0.98790782
 0.98809464 0.9882781  0.98846052 0.98864107 0.98881906 0.98899416
 0.98916492 0.98933429 0.98950092 0.98966268 0.98982379 0.98998309
 0.99014053 0.99029646 0.99045174 0.99060594 0.99075837 0.99090917
 0.99105741 0.9912038  0.99134783 0.99149004 0.99163127 0.99176851
 0.99190482 0.99203949 0.99217257 0.99230504 0.99243537 0.99256187
 0.99268682 0.99281043 0.99293281 0.99305415 0.99317312 0.99329094
 0.99340707 0.99352089 0.99363296 0.99374435 0.99385497 0.99396444
 0.99407296 0.99417892 0.99428382 0.99438713 0.99448749 0.99458719
 0.99468534 0.99478185 0.99487815 0.99497332 0.99506696 0.99515723
 0.99524738 0.99533701 0.99542414 0.99551089 0.99559608 0.99567871
 0.99576023 0.99584086 0.99591942 0.99599663 0.99607367 0.99615007
 0.99622473 0.99629678 0.99636702 0.99643639 0.99650503 0.99657233
 0.99663872 0.99670382 0.99676805 0.99683164 0.99689441 0.99695662
 0.99701812 0.99707788 0.99713701 0.99719547 0.99725295 0.99730974
 0.99736608 0.99742112 0.99747529 0.99752795 0.99757986 0.99763162
 0.99768191 0.99773174 0.99778125 0.99783022 0.99787751 0.99792419
 0.99797001 0.99801463 0.99805906 0.99810196 0.99814413 0.99818615
 0.99822587 0.99826552 0.99830383 0.99834192 0.99837904 0.99841578
 0.99845235 0.99848787 0.99852302 0.99855781 0.99859204 0.99862558
 0.99865881 0.99869103 0.99872314 0.99875468 0.9987857  0.99881617
 0.99884596 0.99887543 0.99890457 0.99893245 0.99896018 0.99898744
 0.99901428 0.99904054 0.99906604 0.99909121 0.99911598 0.99913998
 0.99916339 0.99918613 0.99920882 0.9992309  0.99925205 0.99927264
 0.99929281 0.99931293 0.99933241 0.99935173 0.99937052 0.99938917
 0.99940761 0.99942553 0.99944322 0.99945986 0.99947601 0.99949192
 0.9995072  0.9995224  0.99953758 0.99955248 0.99956713 0.99958127
 0.99959517 0.99960899 0.99962208 0.99963487 0.99964716 0.99965898
 0.99967056 0.99968186 0.99969285 0.99970335 0.99971382 0.99972401
 0.99973395 0.99974366 0.9997531  0.99976243 0.99977154 0.99978033
 0.99978902 0.99979736 0.99980557 0.99981371 0.99982167 0.99982932
 0.9998365  0.99984342 0.99985018 0.99985686 0.99986346 0.99986978
 0.99987574 0.99988148 0.99988705 0.99989244 0.99989766 0.99990285
 0.99990781 0.99991257 0.99991708 0.99992155 0.99992581 0.99992999
 0.99993415 0.99993814 0.99994192 0.99994548 0.99994902 0.99995224
 0.99995534 0.9999584  0.99996142 0.99996416 0.99996686 0.99996952
 0.99997203 0.99997448 0.99997687 0.99997912 0.99998116 0.99998312
 0.99998497 0.99998657 0.999988   0.99998936 0.9999906  0.99999181
 0.99999297 0.99999409 0.99999505 0.99999591 0.99999674 0.99999752
 0.99999828 0.9999989  0.99999933 0.99999967 1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.         1.         1.         1.        ]
In [76]:
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.singular_values_ )+1),myPCA.singular_values_ ,alpha=0.8,marker='.');
#La nueva base son los vectores propios de la matriz de covarianza.
y_label = plt.ylabel('Vectores propios');
x_label = plt.xlabel('Componentes');
plt.title('Scree plot');
In [77]:
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
         np.cumsum(myPCA.explained_variance_ratio_),
         c='red',marker='.',
         label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
Out[77]:
<matplotlib.lines.Line2D at 0x14695f310>
In [78]:
transformed_train = myPCA.transform(X_train_standarized_bin[X_train_bin_2.columns])
transformed_train

X_train_standarized_bin[['PC1','PC2','PC3']] = transformed_train[:,:3]

fig = plt.figure(figsize=(8,8))
_ = sns.scatterplot(x='PC1', y='PC2', data=X_train_standarized_bin, hue=y_train, palette='tab10')

Ahora eligiremos un número de componentes y obtendremos las matrices de datos transformadas y ajustaremos los modelos de Naïve Bayes y KNN¶

Probaremos como se comportan los modelos para un cierto número de componentes, así que podemos intentar ver como se comporta el cross-validation score para los distintos números de componentes y eligiremos los primeros k componentes principales. Usaremos los componentes de PCA para reducir la dimensionalidad y comprobar si podemos reducir el tamaño sin comprometer en exceso la calidad del resultado.

Empezaremos por el modelo de Naïve Bayes Gausiano:

Naïve Bayes Gausiano¶

In [79]:
X_train_standarized = X_train_copia.copy()
X_test_standarized = X_test_copia.copy()

scaler = StandardScaler()

X_train_standarized[data_columns] = scaler.fit_transform(X_train_copia[data_columns])
X_test_standarized[data_columns] = scaler.transform(X_test_copia[data_columns])

myPCA = PCA().fit(X_train_standarized[data_columns]);

transformed_train = myPCA.transform(X_train_standarized[X_train_copia.columns])
transformed_test = myPCA.transform(X_test_standarized[X_train_copia.columns])

nc = 30
X_train_pca_todas = scaler.fit_transform(transformed_train[:,:])
X_train_pca_s = scaler.fit_transform(transformed_train[:,:nc])
X_test_pca_s = scaler.transform(transformed_test[:,:nc])
In [80]:
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
         np.cumsum(myPCA.explained_variance_ratio_),
         c='red',marker='.',
         label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
Out[80]:
<matplotlib.lines.Line2D at 0x147273370>
In [81]:
gnb = GaussianNB()
print(np.mean(cross_val_score(gnb,X_train_pca_todas,y_train,cv=10)))
print(np.mean(cross_val_score(gnb,X_train_pca_s,y_train,cv=10)))
0.49446412102898174
0.6825373310048467
In [82]:
# NB Gaussià k components matriu sense binaritzar
_list = []

for i in range(1, X_train_pca_s.shape[1]+1):
    score = cross_val_score(gnb, X_train_pca_s[:,:i], y_train, cv=10).mean()
    print(i, score)
    _list.append(score)
    
plt.plot(_list, '-o')
plt.xlabel('Número de componentes principales')
plt.ylabel('cross-validation score')
plt.title('Clasificación')
plt.xticks(np.arange(X_train_pca_s.shape[1]), np.arange(1, X_train_pca_s.shape[1]+1))
plt.axhline(y = np.mean(cross_val_score(gnb,X_train_pca_s,y_train,cv=10)), color='g', linestyle='-');
1 0.4395272060122049
2 0.4769592645644879
3 0.7536604987932422
4 0.749227380648706
5 0.7472337774463826
6 0.7529958008751446
7 0.7649534956733317
8 0.7992901713007475
9 0.7990684418107253
10 0.8037218177893765
11 0.8003993093028277
12 0.8309749229833407
13 0.8407226811608421
14 0.8296425838353315
15 0.837171575456704
16 0.8236583403645781
17 0.8139140160508603
18 0.7919794753056139
19 0.7740316504130448
20 0.7605193964248572
21 0.7556442909561839
22 0.7523203108137276
23 0.7341546808468891
24 0.7297235249102288
25 0.7244103565331712
26 0.7162107803700724
27 0.7095662539489435
28 0.7004861370013539
29 0.6891828385299139
30 0.6825373310048467

Podemos ver que a partir de las 13/15 componentes principales, nuestro cross-validation score decrece significativamente a medida que incrementamos las componentes, esto es así ya que nuestros datos estan ciertamente correlacionados y no son independientes como asume Naïve Bayes. Si vamos añadinendo componentes solo empeorará nuestro score.

Evaluamos la calidad del modelo con 30 componentes para el NB Gausiano¶

In [83]:
gnb_model = GaussianNB().fit(X_train_pca_s, y_train)
In [84]:
print(classification_report(gnb_model.predict(X_test_pca_s), y_test))
              precision    recall  f1-score   support

           4       0.44      0.81      0.57       135
           7       0.68      0.97      0.80       174
           9       0.93      0.53      0.67       446

    accuracy                           0.68       755
   macro avg       0.68      0.77      0.68       755
weighted avg       0.78      0.68      0.68       755

Excepto para la clase del 4, vemos que las relaciones precision-recall han mejorado, de forma muy notable para la clase del 7. Tenemos que el recall de la clase 4 ha disminuido y juntamente con el precision de la clase del 9. Seguimos teniendo clases desbalanceadas, pero se ha reducido.

Además, vemos que nuestro modelo usando 30 componentes tiene una mayor accuracy que cuando considerábamos todas la componentes principales. Esto es así ya que al no añadir todas las componentes tendremos componentes que no están muy correlacionadas entre sí y, por lo tanto, tendremos mejores resultados. Empeorará si usamos píxeles con una variación pequeña y se descartaran al hacer el PCA antes que aplicando Naïve Bayes.

In [85]:
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(gnb_model, X_test_pca_s, y_test, display_labels=clases, ax=plt.subplot());
In [86]:
plt.figure(figsize=(8,8));
roc_auc(gnb_model, X_train_pca_s, y_train, X_test_pca_s, y_test);

Vemos que tenemos una mejor media i que la AUC de la clase del 9 es significativamente mucho mejor, ja que hemos pasado de una AUC=0.68 a una AUC=0.89. Además tenemos una mejor media, pasando de ser un 0.85 a un 0.92.

Naïve Bayes Bernoulli¶

In [87]:
X_train_bin = Binarizer(threshold=0.5).transform(X_train_copia)
X_test_bin  = Binarizer(threshold=0.5).transform(X_test_copia)

X_train_bin.shape, X_test_bin.shape
Out[87]:
((4514, 784), (755, 784))
In [88]:
X_train_bin = pd.DataFrame(X_train_bin)
X_test_bin = pd.DataFrame(X_test_bin)

X_train_bin.shape, X_test_bin.shape

X_train_bin_2 = X_train_bin.copy()
X_test_bin_2 = X_test_bin.copy()
In [89]:
X_train_standarized_bin = X_train_bin_2.copy()
X_test_standarized_bin = X_test_bin_2.copy()

myPCA = PCA().fit(X_train_standarized_bin[data_columns]);

transformed_train_bin = myPCA.transform(X_train_standarized_bin[X_train_bin_2.columns])
transformed_test_bin = myPCA.transform(X_test_standarized_bin[X_test_bin_2.columns])

nc = 100
X_train_pca_todas_bin = scaler.fit_transform(transformed_train_bin[:,:])
X_train_pca_s_bin = scaler.fit_transform(transformed_train_bin[:,:nc])
X_test_pca_s_bin = scaler.transform(transformed_test_bin[:,:nc])
In [90]:
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
         np.cumsum(myPCA.explained_variance_ratio_),
         c='red',marker='.',
         label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
Out[90]:
<matplotlib.lines.Line2D at 0x145786140>
In [91]:
bnb = BernoulliNB()
print(np.mean(cross_val_score(bnb, X_train_pca_todas_bin, y_train, cv=10)))
print(np.mean(cross_val_score(bnb, X_train_pca_s_bin, y_train, cv=10)))
0.8055020308851519
0.7753625179051469
In [92]:
# NB Bernoulli k components matriu sense binaritzar
_list = []

for i in range(1, X_train_pca_s_bin.shape[1]+1):
    score = cross_val_score(bnb, X_train_pca_s_bin[:,:i], y_train, cv=10).mean()
    print(i, score)
    _list.append(score)
    
plt.plot(_list, '-o')
plt.xlabel('Número de componentes principales')
plt.ylabel('cross-validation score')
plt.title('Clasificación')
plt.xticks(np.arange(X_train_pca_s_bin.shape[1]), np.arange(1, X_train_pca_s_bin.shape[1]+1))
plt.axhline(y = np.mean(cross_val_score(bnb,X_train_pca_s_bin,y_train,cv=10)), color='g', linestyle='-');
1 0.45192247316680734
2 0.4951288189470793
3 0.6612684692816357
4 0.6612684692816357
5 0.6672522222004199
6 0.6650388517159507
7 0.6712404097090046
8 0.680988167886506
9 0.708227537625336
10 0.7532042854620018
11 0.7518778329376213
12 0.7521015246355198
13 0.7543193100877107
14 0.7534328826795911
15 0.7649480996016718
16 0.7649476090497027
17 0.7631786786492161
18 0.7640636344014284
19 0.7647312756313404
20 0.7682730608480662
21 0.7660587092596589
22 0.7700459156643055
23 0.7713758020524695
24 0.7700459156643055
25 0.7727047073366953
26 0.7724844495025802
27 0.7735891725369386
28 0.7749180778211644
29 0.7769121715754567
30 0.7746973294350803
31 0.7764721464591959
32 0.776473127563134
33 0.7722627200125581
34 0.7753610462492396
35 0.7749215116849478
36 0.7751427506230011
37 0.7760291780311206
38 0.7727066695445715
39 0.7735930969526912
40 0.7716014559582443
41 0.7720439338343504
42 0.7698300727979122
43 0.7696063811000137
44 0.7700493495280891
45 0.7693871043698369
46 0.7720458960422267
47 0.7753679139768067
48 0.7738162980986205
49 0.7751442222789083
50 0.7758084296450366
51 0.7735926064007221
52 0.7773566116594391
53 0.7744780527049036
54 0.7749215116849479
55 0.7733689147028235
56 0.7753639895610541
57 0.7762504169691737
58 0.7773615171791299
59 0.776251888625081
60 0.7780222906814748
61 0.7771368443772932
62 0.7758069579891294
63 0.7764706748032886
64 0.776472637011165
65 0.776472637011165
66 0.7789111708494397
67 0.7778025233993289
68 0.779795145497714
69 0.7804603339677806
70 0.7789092086415635
71 0.7782464729313423
72 0.7789106802974707
73 0.7802381139257893
74 0.7802381139257892
75 0.7815630947942624
76 0.7815630947942626
77 0.7797917116339306
78 0.7784608441418285
79 0.7797922021858995
80 0.7813428369601476
81 0.7800129505719837
82 0.7793487432058553
83 0.7804559190000588
84 0.7833354590585326
85 0.7822268116084218
86 0.7802346800620058
87 0.7813418558562094
88 0.7804559190000588
89 0.7824500127543511
90 0.7784608441418285
91 0.7806756862822046
92 0.7791255420599258
93 0.7782391146518063
94 0.7789038125699037
95 0.7789038125699037
96 0.7780193473696604
97 0.7751383356552795
98 0.7746938955712969
99 0.7766919137413417
100 0.7753625179051469

Podemos ver que a partir de las 20/22 componentes nuestro score se mantiene, y va oscilando levemente, en este caso, podemos notar que para conseguir un mayor score, vamos a necesitar de todas las componentes, sino tendremos un acuracy claramente inferior al que teníamos sin la reducción de las componentes.

Evaluamos la calidad del modelo para una NB Bernoulli¶

In [93]:
bnb_model = BernoulliNB().fit(X_train_pca_s_bin, y_train)
In [94]:
print(classification_report(bnb_model.predict(X_test_pca_s_bin), y_test, target_names=clases))
              precision    recall  f1-score   support

           4       0.70      0.85      0.77       206
           7       0.82      0.82      0.82       252
           9       0.84      0.72      0.78       297

    accuracy                           0.79       755
   macro avg       0.79      0.80      0.79       755
weighted avg       0.80      0.79      0.79       755

Notamos que todas la relaciones precision-recall se han visto afectadas. Ahora si que necesitamos de muchas mas componentes, nos faltaran componentes que no esten correlacionadas para augmentar el acierto del modelo.

In [95]:
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(bnb_model, X_test_pca_s_bin, y_test, display_labels=clases, ax=plt.subplot());
In [96]:
plt.figure(figsize=(8,8));
roc_auc(bnb_model, X_train_pca_s_bin, y_train, X_test_pca_s_bin, y_test);

Como es de esperar, todas la AUC han disminuido.

KNN con la matriz original de datos¶

In [97]:
X_train_standarized = X_train_copia.copy()
X_test_standarized = X_test_copia.copy()

scaler = MinMaxScaler()

X_train_standarized[data_columns] = scaler.fit_transform(X_train_copia[data_columns])
X_test_standarized[data_columns] = scaler.transform(X_test_copia[data_columns])

myPCA = PCA().fit(X_train_standarized[data_columns]);

transformed_train = myPCA.transform(X_train_standarized[X_train_copia.columns])
transformed_test = myPCA.transform(X_test_standarized[X_train_copia.columns])

nc = 30
X_train_pca_todas = scaler.fit_transform(transformed_train[:,:])

X_train_pca_s = scaler.fit_transform(transformed_train[:,:nc])
X_test_pca_s = scaler.transform(transformed_test[:,:nc])

knn =  KNeighborsClassifier()

print(np.mean(cross_val_score(knn, X_train_pca_todas, y_train, cv=10)))
print(np.mean(cross_val_score(knn, X_train_pca_s, y_train, cv=10)))
0.8101465769283598
0.9667695190628495
In [98]:
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
         np.cumsum(myPCA.explained_variance_ratio_),
         c='red',marker='.',
         label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
Out[98]:
<matplotlib.lines.Line2D at 0x13758dff0>
In [115]:
# KNN k components matriu sense binaritzar
_list = []

for i in range(1, X_train_pca_s.shape[1]+1):
    score = cross_val_score(knn, X_train_pca_s[:,:i], y_train, cv=10).mean()
    print(i, score)
    _list.append(score)
    
plt.plot(_list, '-o')
plt.xlabel('Número de componentes principales')
plt.ylabel('cross-validation score')
plt.title('Clasificación')
plt.xticks(np.arange(X_train_pca_s.shape[1]), np.arange(1, X_train_pca_s.shape[1]+1))
plt.axhline(y = np.mean(cross_val_score(knn,X_train_pca_s,y_train,cv=10)), color='g', linestyle='-');
1 0.42289307929282033
2 0.564242685870141
3 0.7556506681317818
4 0.7957449522202382
5 0.8460314345701784
6 0.8568824441261308
7 0.875933520397151
8 0.894538194376312
9 0.9069481780899868
10 0.9293256872633087
11 0.9339731766183309
12 0.9421747149893059
13 0.9457199340698154
14 0.9514790141867631
15 0.9536963090869847
16 0.9559126228832682
17 0.9554696544551928
18 0.9579072071895297
19 0.9601191060180915
20 0.9583501756176049
21 0.9612287345721405
22 0.9601245020897513
23 0.9621166336361675
24 0.9607857661440654
25 0.9618924513863
26 0.9630010988364107
27 0.9625586209603044
28 0.9647739536526501
29 0.9665463179169201
30 0.9667695190628495

Podemos ver que con aproximadamente 30 componentes tenemos un muy buen acierto

Evaluamos la calidad del modelo para una KNN con la matriz de datos sin binarizar¶

In [100]:
param = {'n_neighbors':[1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 15], 
          'weights':['distance', 'uniform'], 
          'leaf_size':[1, 5, 10, 20, 25, 30],
          'metric': ['l2', 'l1', 'cosine']}

knn_gs =  GridSearchCV(knn,param,cv=10, n_jobs=-1)
knn_gs.fit(X_train_pca_s, y_train);
/usr/local/lib/python3.10/site-packages/joblib/externals/loky/process_executor.py:700: UserWarning:

A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak.

In [101]:
show_html(pd.DataFrame(knn_gs.cv_results_).loc[:,['params', 'mean_test_score','rank_test_score']].sort_values(by='rank_test_score').head().to_html())
params mean_test_score rank_test_score
54 {'leaf_size': 1, 'metric': 'cosine', 'n_neighbors': 6, 'weights': 'distance'} 0.973194 1
252 {'leaf_size': 20, 'metric': 'cosine', 'n_neighbors': 6, 'weights': 'distance'} 0.973194 1
186 {'leaf_size': 10, 'metric': 'cosine', 'n_neighbors': 6, 'weights': 'distance'} 0.973194 1
120 {'leaf_size': 5, 'metric': 'cosine', 'n_neighbors': 6, 'weights': 'distance'} 0.973194 1
318 {'leaf_size': 25, 'metric': 'cosine', 'n_neighbors': 6, 'weights': 'distance'} 0.973194 1
In [102]:
print(classification_report(knn_gs.predict(X_test_pca_s), y_test,target_names=clases))
              precision    recall  f1-score   support

           4       0.98      0.99      0.98       246
           7       0.98      0.98      0.98       250
           9       0.98      0.96      0.97       259

    accuracy                           0.98       755
   macro avg       0.98      0.98      0.98       755
weighted avg       0.98      0.98      0.98       755

Vemos que al aplicar la reducción, el modelo de KNN funciona un 0.01 mejor, no es ningun cambio significativo, pero hemos conseguido mejorar un poco el modelo, teniendo todas la relaciones precision-recall superiores a las que teníamos antes. Vemos que para la clase del 4, no se confunde con el 7.

In [103]:
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(knn_gs, X_test_pca_s, y_test, display_labels=clases, ax=plt.subplot());
In [104]:
plt.figure(figsize=(8,8));
roc_auc(knn_gs, X_train_pca_s, y_train, X_test_pca_s, y_test);

Como podemos ver obtenenemos un AUC perfecta para todas las clases. Por lo tanto, para cualesquiera clase, tenemos un 100% de predicciones correctas.

KNN con la matriz datos binarizada¶

In [105]:
X_train_bin = Binarizer(threshold=0.5).transform(X_train_copia)
X_test_bin  = Binarizer(threshold=0.5).transform(X_test_copia)

X_train_bin.shape, X_test_bin.shape
Out[105]:
((4514, 784), (755, 784))
In [106]:
X_train_bin = pd.DataFrame(X_train_bin)
X_test_bin = pd.DataFrame(X_test_bin)

X_train_bin.shape, X_test_bin.shape

X_train_bin_2 = X_train_bin.copy()
X_test_bin_2 = X_test_bin.copy()
In [107]:
X_train_standarized_bin = X_train_bin_2.copy()
X_test_standarized_bin = X_test_bin_2.copy()

myPCA = PCA().fit(X_train_standarized_bin[data_columns]);

transformed_train_bin = myPCA.transform(X_train_standarized_bin[X_train_bin_2.columns])
transformed_test_bin = myPCA.transform(X_test_standarized_bin[X_test_bin_2.columns])

nc = 30
X_train_pca_todas_bin = scaler.fit_transform(transformed_train_bin[:,:])
X_train_pca_s_bin = scaler.fit_transform(transformed_train_bin[:,:nc])
X_test_pca_s_bin = scaler.transform(transformed_test_bin[:,:nc])

knn =  KNeighborsClassifier()

print(np.mean(cross_val_score(knn, X_train_pca_todas_bin, y_train, cv=10)))
print(np.mean(cross_val_score(knn, X_train_pca_s_bin, y_train, cv=10)))
0.7826923454270746
0.9632301866059689
In [108]:
fig = plt.figure(figsize=(5,5));
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),myPCA.explained_variance_ratio_ ,alpha=0.8,marker='.',label="Variancia Explicada");
y_label = plt.ylabel('Variancia explicada');
x_label = plt.xlabel('Componentes');
plt.plot(range(1,len(myPCA.explained_variance_ratio_ )+1),
         np.cumsum(myPCA.explained_variance_ratio_),
         c='red',marker='.',
         label="Variancia explicada acumulativa");
plt.legend();
plt.title('Porcentaje de variancia explicada por componente');
plt.axhline(y=0.85, color='g', linestyle='-')
Out[108]:
<matplotlib.lines.Line2D at 0x1493dc6a0>
In [109]:
# NB Bernoulli k components matriu sense binaritzar
_list = []

for i in range(1, X_train_pca_s_bin.shape[1]+1):
    score = cross_val_score(knn, X_train_pca_s_bin[:,:i], y_train, cv=10).mean()
    print(i, score)
    _list.append(score)
    
plt.plot(_list, '-o')
plt.xlabel('Número de componentes principales')
plt.ylabel('cross-validation score')
plt.title('Clasificación')
plt.xticks(np.arange(X_train_pca_s_bin.shape[1]), np.arange(1, X_train_pca_s_bin.shape[1]+1))
plt.axhline(y = np.mean(cross_val_score(knn,X_train_pca_s_bin,y_train,cv=10)), color='g', linestyle='-');
1 0.43088466142103093
2 0.5573744677511134
3 0.7396969369935051
4 0.7802317367501913
5 0.8453608500284518
6 0.856890783509605
7 0.8723863391087653
8 0.8914369248278163
9 0.9082814983419343
10 0.9295459450974235
11 0.9315434727154995
12 0.9426167023134429
13 0.9430621235013638
14 0.9477140278241076
15 0.9499303416203911
16 0.9457218962776917
17 0.9499308321723603
18 0.9497086121303691
19 0.9525886427408121
20 0.9501501089025371
21 0.9539165669210995
22 0.9525886427408119
23 0.9550296293389321
24 0.9579081882934679
25 0.9568000313953261
26 0.9585728862115653
27 0.9574676726252379
28 0.9596820242136452
29 0.9621185958440439
30 0.9632301866059689

Vemos que usando 30 componentes nos es suficiente para alanzar una buen cross-validation score

Evaluamos la calidad del modelo para una KNN con la matriz de datos binarizada¶

In [110]:
param = {'n_neighbors':[1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 15], 
          'weights':['distance', 'uniform'], 
          'leaf_size':[1, 5, 10, 20, 25, 30],
          'metric': ['l2', 'l1', 'cosine']}

knn_gs =  GridSearchCV(knn,param,cv=10, n_jobs=-1)
knn_gs.fit(X_train_pca_s_bin, y_train);
In [111]:
show_html(pd.DataFrame(knn_gs.cv_results_).loc[:,['params', 'mean_test_score','rank_test_score']].sort_values(by='rank_test_score').head().to_html())
params mean_test_score rank_test_score
210 {'leaf_size': 20, 'metric': 'l2', 'n_neighbors': 7, 'weights': 'distance'} 0.966107 1
78 {'leaf_size': 5, 'metric': 'l2', 'n_neighbors': 7, 'weights': 'distance'} 0.966107 1
342 {'leaf_size': 30, 'metric': 'l2', 'n_neighbors': 7, 'weights': 'distance'} 0.966107 1
144 {'leaf_size': 10, 'metric': 'l2', 'n_neighbors': 7, 'weights': 'distance'} 0.966107 1
12 {'leaf_size': 1, 'metric': 'l2', 'n_neighbors': 7, 'weights': 'distance'} 0.966107 1
In [112]:
print(classification_report(knn_gs.predict(X_test_pca_s_bin), y_test,target_names=clases))
              precision    recall  f1-score   support

           4       0.97      0.98      0.98       248
           7       0.98      0.96      0.97       255
           9       0.95      0.96      0.95       252

    accuracy                           0.96       755
   macro avg       0.96      0.96      0.96       755
weighted avg       0.96      0.96      0.96       755

Apenas hay diferencias de este modelo con el mismo que habíamos relalizado anteriormente. Solo diferencias no sustanciales en el mean_test_score, puesto que este ha disminuido un poco.

In [113]:
plt.figure(figsize=(8,8));
ConfusionMatrixDisplay.from_estimator(knn_gs, X_test_pca_s_bin, y_test, display_labels=clases, ax=plt.subplot());
In [114]:
plt.figure(figsize=(8,8));
roc_auc(knn_gs, X_train_pca_s_bin, y_train, X_test_pca_s_bin, y_test);

¿Por qué sería más adecuado usar el Naïve Bayes con esta transformación?¶

Usar Naïve Bayes Gausiano con un cierto número de componentes es mucho más adecuado que usar cualesquiera de los modelos de KNN con la transformación que les hemos aplicado. Esto es así ya que la relación de calidad/tiempo de los modelos de KNN comparada con los modelos de NB es mucho peor. Para conseguir una buena calidad en KNN necesitamos mucho más tiempo que para los modelos de NB auqnue estos tengas una accuracy inferior. Aún así, vemos que estos el modelo de NB Gausiano, al escoger un cierto número de componentes con respecto a cuando cogíamos todas las componentes ha mejorado, y por otro lado, la acuracy del modelo de NB Bernoulli ha disminuido.

Determinar el número de componentes es crucial ya que al usar PCA para la reducción de dimensionalidad, hemos de determinar con acierto el número de dimensiones (la proporción de la varianza original) que queremos dejar en los datos.

Si no reducimos la dimensionalidad lo suficiente, no filtraremos el ruido y pasará que a medida que añadimos compoentes en NB Gausiano tendremos un peor score. Por otro lado, si eliminamos demasiadas dimensiones, corremos el riesgo de eliminar información valiosa, como sucede en NB Bernoulli.

Usar KNN con esta transformación es más asequible, pero no nos hará tener un clasificador de códigos postales bueno para una predicción en tiempo real ya que es demasiado costoso, aunque haga un 100% de predicciones correctas. Usar un NB que no nos de esta fiabilidad pero si rapidez, nos hace más eficientes.


Vemos que a NB Gausiano a medida que augmentamos el número de componentes solo empeora, ya que tenemos píxeles que están en cierta forma correlacionados y no son independientes. Al tener esta cantidad de features, podríamos probar de usar una SVM pero alomejor nos cuesta encontrar un poco el kernel correcto, podemos apostar por uno no-lineal, ya que al ver el resultado que nos ha dado el t-SNE, podemos intuir que entre nuestros datos tenemos no-linealidades.

Comprobación aquí: SVM al subconjunto MNIST

¿Qué ventajas/inconvenientes tendría el trabajar con los datos transformados?¶

Vemos que trabajando con los datos transformados, i.e con menor dimensionalidad, el hecho de poder ajustar los modelos KNN se vuelve más practicable para este caso práctico ya que el tiempo de ejecución se ha reducido considerablemente y la precisión no se ha visto perjudicada, por lo tanto vemos que reduciendo la dimensionalidad hace que los modelos KNN funcionen de forma más eficiente y manteniendo la calidad que tenían cuando usábamos todos los píxeles de las imágenes. Vemos que solamente usando 30 componentes tenemos suficente para llegar a la misma calidad que cúando usábamos las 784.

Por otro lado, también vemos que transformando los datos, después de la aplicación del PCA y quedándonos solo con 30 componentes la accuracy del modelo de NB Gausiano ha mejorado de forma significativa, pasando de un 0.57 a un 0.68. A medida que ibámos añadiendo más componentes podíamos ver que la $R^{2}$ del conjunto de validación disminuia. Esto se debe a que en realidad la asunción de que los píxeles son independientes no es corercta, ya que algunos si que estan altamente correlacionadas y no son independientes. Además el PCA tampoco nos ha funcionado demasiado ya que pondera cada pixel por igual y no tiene en cuenta la clase.

Además un inconveniente es que para el modelo de NB Bernouilli, ha sido arriesgado realizar esta reducción de dimensionalidad, ya que hemos perdido información valiosa y nos ha derivado en un peor clasificador.

En general pero, trabajamos con menos dimensiones, y esto siempre nos viene bien ya que el tiempo de cómputo va a dismuinir, y también la practicabilidad a la hora de gestionar un recurso como es la memoria donde cargaremos el modelo.

¿Qué modelo de entre todos elegirías para reconocer códigos postales? Razona tu respuesta.¶

Para razonar qué modelo de entre los cuatro escogeria para reconocer los códigos postales que se encuentran cartas, tendré en cuenta varios factores que me parecen cruciales para la elección.

Para saber cuáles son factores, hemos de retroceder al enunciado y fijarnos en el hecho de que se nos dice de forma indirecta que queremos:

  • clasificar las cartas en el menor tiempo possible ya que hacerlo a mano consume demasiado tiempo
  • hacer la clasificación de manera fiable, puesto que hacerlo a mano no lo es del todo y además es cansado

Por lo tanto, nuestra elección del modelo estará estrechamente condicionada por los dos factores de arriba. Así pues, tendremos que escoger un modelo que tenga un equilibrio de ambos, es decir, que no tarde mucho en dar la clasificación y que lo haga relativamente bien, es decir que nos podamos fiar de la clasificación que hace de los códigos para todas las cartas.

Lo que hemos de interpretar del enunciado es que lo que realmente queremos es dar una predicción en tiempo real de los códigos postales para clasificar las cartas que nos lleguen. Esta predicción en tiempo real, ha de ser lo más rápida y fiable posible.

Hemos visto que los distintos modelos tienen una $R^{2}$ distinta, podemos verlas como siguen:

  • Naïve Bayes Gausiano: 0.57
  • Naïve Bayes Bernoulli: 0.86
  • KNN matriz datos original: 0.97
  • KNN matriz datos binarizada: 0.96

Además estas $R^{2}$ se han obtenido sin hacer aún la reducción de la dimensionalidad para posteriormente pasarlo a los modelos, es decir sin usar los componentes de PCA para reducir las dimensiones y ver como ha afectado a la calidad del resultado.

Como podemos ver hay una gran diferencia entre las $R^{2}$ del modelo de Naïve Bayes Gausiano y el resto de modelos.

Una vez realizada la transformación, hemos elegido un número de componentes, nc=30 y hemos obtenido las matrices de datos transformadas. Una vez ajustados los nuevos modelos, tenemos las $R^{2}$, como siguen:

  • Naïve Bayes Gausiano: 0.68
  • Naïve Bayes Bernoulli: 0.79
  • KNN matriz datos original: 0.98
  • KNN matriz datos binarizada: 0.96

Además también hay una diferencia considerable entre el tiempo de ejecución entre los modelos de Naïve Bayes y los KNN

Tenemos por un lado que el tiempo de ejecución de los Naïve Bayes es $\Theta(1)$ mientras que lo mejor que lo pueden hacer los modelos de KNN basados en KDTree es $\Theta(log(N))$, siendo N el numero de data points que tengamos. Por lo tanto como más grande sea el tamaño de los datos aplicar un KNN se vuelve un poco impracticable si no le aplicamos alguna reducción o alguna tuneada importante en los hiperparámetros.

Por lo tanto, los modelos KNN funcionan mejor cuando los datos son pequeños, pero si sabemos que el tamaño de nuestros datos es grande o va aumentando, seria aconsejable elegir unos modelos de Naive Bayes.

Aunque, KNN a veces puede ser una buena opción en algunos entornos, especialmente si los datos que tenemos tiene baja dimensión o si les aplicamos una reducción de dimensionalidad, vemos que usar KNN para clasificación de imágenes es un poco impracticable, por el tiempo de ejecución, ya que por el contrario son los modelos que mejor fiabilidad tienen, ya que producen mejores resultados que Naïve Bayes. Pero el problema es que las imágenes suelen tener grandes dimensiones, i.e pueden contener muchos píxeles.

Por lo tanto, hemos visto que sin aplicar la transformación a los datos, quedarnos con alguno de los modelos de KNN seria inviable ya que el tiempo de ejecución de estos no nos permitiria poder clasificar los códigos postales de las cartas de forma rápida, aunque si de forma muy fiable.

Dada esta situación, y después de aplicar la transformación del PCA a las matrices de datos, y quedándonos con solo 30 componentes, hemos podido ver que el tiempo de ejecución de los modelos KNN es menor, aunque sigue siendo demasiado alta en comparación con los modelos de Naïve Bayes.

Es por esto que creo que la mejor opción seria tener como clasificador al modelo de NB Bernoulli sin la reducción de dimensionalidad. Este modelo funciona mejor que el Naïve Bayes en ambos casos(sin y con transformación) además en tiempo de ejecución va a la par que el modelo de NB Gausiano. El ~10% más de acuracy que nos dan los modelos KNN con respecto a este, no nos compensa, ya que debemos ser eficientes a la hora de clasificar las cartas, puesto que no seria rentable clasificar menos cartas pero de forma segura a, más cartas, y con solo un ~10% de clasificaciones erróneas. El servicio de correos preferiria asumir este coste extra surgido de la mala clasifiación a ser menos eficiente en tiempo.

Si el servicio de correos estuviese dispuesto a asumir un coste un poco superior, alomejor podria plantearse usar el método de KNN con la matriz sin binarizar y con la reducción de la dimensionalidad.